{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Readme\n",
    "## About Environment\n",
    "\n",
    "Pytorch Version\n",
    "PyTorch Version: 1.12.1\n",
    "PyTorch CUDA Version: 10.2\n",
    "PyTorch cuDNN Version: 7605\n",
    "Current Device info Tesla P100-PCIE-12GB \n",
    "\n",
    "## 关于Cos位置编码\n",
    "数学原理\n",
    "$$ \n",
    "\\begin{array}{ll} & PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}})\\\\  & PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}})\\end{array}\n",
    "$$\n",
    "`d_model`：最后除以 d_model，使得缩放率随 d_model 增加而递减。这确保了较小的维度（i 较小）在位置编码中变化较快，而较大的维度（i 较大）变化较慢。这种设计有助于在较低的维度中编码局部的细粒度信息，而在较高的维度中编码全局的粗粒度信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 依赖声明"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/envs/torchenv/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "# 科学计算 Lib\n",
    "import numpy as np\n",
    "\n",
    "# 绘图 Lib\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# 深度学习 pytorch Lib\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.utils.data import DataLoader, Dataset\n",
    "from torch.nn.utils.rnn import pad_sequence"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 依赖引入检查"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyTorch Version: 1.12.1\n",
      "PyTorch CUDA Version: 10.2\n",
      "PyTorch cuDNN Version: 7605\n",
      "Current Device info Tesla P100-PCIE-12GB\n"
     ]
    }
   ],
   "source": [
    "# Torch version check\n",
    "print(\"PyTorch Version:\", torch.__version__)\n",
    "print(\"PyTorch CUDA Version:\", torch.version.cuda)\n",
    "print(\"PyTorch cuDNN Version:\", torch.backends.cudnn.version())\n",
    "print(\"Current Device info\", torch.cuda.get_device_name(0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 位置编码模块定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PositionalEncoder:\n",
    "    \"\"\"计算位置编码并将其与词嵌入加和，形成每个位置的最终表示。\n",
    "    \"\"\"    \n",
    "    def __init__(self) -> None:\n",
    "        \"\"\"\n",
    "        create_padding_mask \n",
    "        \n",
    "        \"\"\"\n",
    "        self.pad = 1\n",
    "        self.init_pos_encoding()\n",
    "\n",
    "    def init_pos_encoding(self, position_model: int = 50,d_model: int = 540) -> None:\n",
    "        self.pos_encoding = self.positional_encoding(position_model, d_model)\n",
    "\n",
    "    def get_position_encoding_shape(self) -> \"array\":\n",
    "        # print(self.pos_encoding.shape) # [1,50,512]\n",
    "        return self.pos_encoding.shape\n",
    "\n",
    "    def get_angles(self, pos: np.ndarray, i: np.ndarray, d_model: int) -> np.ndarray:\n",
    "        \"\"\"计算角度  即Sin Cos的参数部分\n",
    "        \n",
    "        pos * angle_rates = 1/(10000^(2i/d))\n",
    "        \n",
    "        Args:\n",
    "            pos (np.ndarray): 位置索引的数组。 形状为 [sentence_length, 1]。\n",
    "            例子，\"I like it\" 的长度是 3，所以 pos 的形状是 [3, 1]。\n",
    "            i (np.ndarray): 维度索引的数组。形状为 [1, d_model]\n",
    "            这里的 d_model 是 512。因此，i 的形状是 [1, 512]。\n",
    "            d_model (int): 位置编码的维度。\n",
    "\n",
    "        Returns:\n",
    "            np.ndarray: 形状为 [sentence_length, d_model] \n",
    "            Example [50,1]*[1,512]=>[50, 512]\n",
    "        \"\"\"\n",
    "        \n",
    "        # Step 1: 计算 i // 2\n",
    "        # 这里 i 是维度索引数组，假设它是一个形状为 [1, 512] 的数组。\n",
    "        half_i = i // 2\n",
    "\n",
    "        # Step 2: 将 d_model 转换为 float32 类型，确保后续计算是浮点数\n",
    "        d_model_float = np.float32(d_model)\n",
    "\n",
    "        # Step 3: 计算 2 * (i // 2) / d_model\n",
    "        # 这里得到的结果仍然是一个形状为 [1, 512] 的数组\n",
    "        # 2*(i//2)保证了2i\n",
    "        exponent = 2 * half_i / d_model_float\n",
    "\n",
    "        # Step 4: 计算 10000^exponent\n",
    "        # 通过 np.power 计算 10000 的 exponent 次幂，结果是一个 [1, 512] 的数组\n",
    "        denominator = np.power(10000, exponent)\n",
    "\n",
    "        # Step 5: 取倒数 1 / (10000^exponent)\n",
    "        # 这部分计算的是1/10000^(2i/d) 即比例缩放系数\n",
    "        # 这里我们得到的是 1 / (10000^exponent)，也是一个形状为 [1, 512] 的数组\n",
    "        angle_rates = 1 / denominator\n",
    "\n",
    "        # Step 6: 位置索引 pos 乘以 angle_rates\n",
    "        # pos 是位置索引的数组，假设形状为 [50, 1] \n",
    "        # 最终得到的 angle_rads 形状为 [50, 512]\n",
    "        angle_rads = pos * angle_rates\n",
    "\n",
    "        return angle_rads\n",
    "\n",
    "\n",
    "    def positional_encoding(self, position_model: int, d_model: int) -> \"torch.tensor\":\n",
    "        \"\"\"位置编码\n",
    "\n",
    "        Args:\n",
    "            position_model (int): 位置编码的序列长度，也就是模型能够处理的最大位置序列。\n",
    "            如果序列长度大于50，这个位置编码可能就不适用了；\n",
    "            如果序列长度小于50，多余的编码就会被忽略。\n",
    "            d_model (int): 位置编码的维度，相当于position encoding的embedding_dim\n",
    "            例如，如果Transformer的每个输入词的嵌入表示（embedding）是512维的\n",
    "            那么位置编码也应该是512维的，这样可以直接与词嵌入相加或组合。\n",
    "\n",
    "        Returns:\n",
    "            torch.tensor:\n",
    "        \"\"\"\n",
    "        angle_rads = self.get_angles(\n",
    "            np.arange(position_model)[:, np.newaxis],  # [50, 1]\n",
    "            np.arange(d_model)[np.newaxis, :],  # [1, d_model=512]\n",
    "            d_model,\n",
    "        )\n",
    "        \n",
    "        angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])  # 2i\n",
    "        angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])  # 2i+2\n",
    "\n",
    "        self.pos_encoding = angle_rads[np.newaxis, ...]  # [50,512]=>[1,50,512]\n",
    "        \n",
    "        return torch.tensor(self.pos_encoding, dtype=torch.float32)\n",
    "    def encode(self, word_list: list):\n",
    "        \"\"\"\n",
    "        Encodes the input list of words by assigning positional encodings.\n",
    "\n",
    "        Args:\n",
    "            word_list (list): List of words to be encoded.\n",
    "\n",
    "        Returns:\n",
    "            torch.Tensor: Encoded words with positional information, shape [len(list), 540].\n",
    "        \"\"\"\n",
    "        sequence_length = len(word_list)\n",
    "        # Ensure position encoding is long enough\n",
    "        if sequence_length > self.pos_encoding.shape[1]:\n",
    "            raise ValueError(\"Sequence length exceeds the maximum positional encoding limit.\")\n",
    "        \"\"\" \n",
    "            实际上,位置编码的结果和具体的Words List是无关的,它只和序列长度有关\n",
    "            这里的切片操作的前提是pos_encoding的3维度\n",
    "            第一维度切片 选择到位置编码矩阵元素 \n",
    "            第二维度切片 只选中我们需要大小的位置编码,即sequence_length\n",
    "            第三维度切片 编码维度大小,默认 540 不变化\n",
    "        \"\"\"\n",
    "        return self.pos_encoding[0, :sequence_length, :]  # Return the positional encoding for each word\n",
    "    \n",
    "    def draw_pos_encoding(self, save: bool = False):\n",
    "        \"\"\"绘制分类图\n",
    "            展示了位置编码矩阵在不同位置和维度上的值\n",
    "            位置编码的目的是为了为每个位置引入唯一的、连续变化的信息，\n",
    "            使得模型能够区分序列中的不同位置。\n",
    "            图表能够展示每个位置和维度上的编码模式，例如：正弦和余弦函数的周期性变化。\n",
    "        Args:\n",
    "            save (bool, optional): _description_. Defaults to False.\n",
    "        \"\"\"        \n",
    "        plt.figure()\n",
    "        # 颜色映射方案，这里选择了红色到蓝色的渐变色\n",
    "        plt.pcolormesh(self.pos_encoding[0], cmap=\"RdBu\")\n",
    "        # 即 d_model，这里是 512。\n",
    "        plt.xlabel(\"Depth\")\n",
    "        plt.xlim((0, 512))\n",
    "        # 即 position，这里是 50。\n",
    "        plt.ylabel(\"Position\")\n",
    "        plt.colorbar()  # 条形bar颜色图例\n",
    "        if save == True:\n",
    "            plt.savefig(result_save + \"pos_encoding.png\")\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 原理分解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "512.0\n",
      "<class 'numpy.float32'>\n"
     ]
    }
   ],
   "source": [
    "# Numpy的浮点数类型\n",
    "d_model = 512\n",
    "d_model_float = np.float32(d_model)\n",
    "print(d_model_float)  # 输出: 512.0\n",
    "print(type(d_model_float))  # 输出: <class 'numpy.float32'>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([2, 3])\n",
      "torch.Size([2])\n",
      "torch.Size([2, 2])\n",
      "tensor([[1, 3],\n",
      "        [4, 6]])\n"
     ]
    }
   ],
   "source": [
    "# 示例张量\n",
    "tensor = torch.tensor([[1, 2, 3],\n",
    "                    [4, 5, 6]]) # \n",
    "print(tensor.shape)\n",
    "# 索引张量\n",
    "indices = torch.tensor([0, 2])\n",
    "print(indices.size())\n",
    "# 使用索引张量切片\n",
    "result = tensor[:, indices]\n",
    "print(result.size())\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "布尔选择逻辑\n",
    "布尔索引之后实际上每个批次经过选择后返回选择的元素,这实际上会导致最终的结果维度下降\n",
    "When you use boolean indexing on a tensor, the result is a flattened version of the selected elements, which often causes a reduction in dimensions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The shape is pad_mask_squeezed torch.Size([2, 4]) The content tensor([[False,  True, False,  True],\n",
      "        [ True, False,  True, False]])\n",
      "The shape is pos_encoding torch.Size([4, 3]) The content tensor([[ 4.,  5.,  6.],\n",
      "        [10., 11., 12.],\n",
      "        [13., 14., 15.],\n",
      "        [19., 20., 21.]])\n"
     ]
    }
   ],
   "source": [
    "pad_mask = torch.tensor([\n",
    "    [[False, True, False, True]],  # 对应第一个批次的掩码\n",
    "    [[True, False, True, False]]  # 对应第二个批次的掩码\n",
    "], dtype=torch.bool) # [2, 1, 4]\n",
    "\n",
    "# 去除维度 1\n",
    "pad_mask_squeezed = pad_mask.squeeze(1)\n",
    "print(\"The shape is pad_mask_squeezed\", pad_mask_squeezed.shape,\"The content\", pad_mask_squeezed)\n",
    "\n",
    "pos_encoding = torch.tensor([\n",
    "    [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],  # 第一个批次\n",
    "    [[13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24]]  # 第二个批次\n",
    "], dtype=torch.float32) # [2,4,3]\n",
    "\n",
    "# pos_encoding = pos_encoding[:, pad_mask_squeezed, :]\n",
    "# pos_encoding = pos_encoding[pad_mask_squeezed]\n",
    "pos_encoding = pos_encoding[pad_mask_squeezed, :]\n",
    "print(\"The shape is pos_encoding\", pos_encoding.shape,\"The content\", pos_encoding)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you need to maintain specific dimensions or keep batch-level structure,you might need to handle the indexing differently or apply masking in a way that maintains the desired dimensions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape of pos_encoding_with_mask: torch.Size([2, 4, 3])\n",
      "Content of pos_encoding_with_mask:\n",
      " tensor([[[ 1.,  2.,  3.],\n",
      "         [ 0.,  0.,  0.],\n",
      "         [ 7.,  8.,  9.],\n",
      "         [ 0.,  0.,  0.]],\n",
      "\n",
      "        [[ 0.,  0.,  0.],\n",
      "         [16., 17., 18.],\n",
      "         [ 0.,  0.,  0.],\n",
      "         [22., 23., 24.]]])\n"
     ]
    }
   ],
   "source": [
    "# Example tensors\n",
    "pad_mask = torch.tensor([\n",
    "    [[False, True, False, True]],  # Mask for batch 0\n",
    "    [[True, False, True, False]]  # Mask for batch 1\n",
    "], dtype=torch.bool)  # [2, 1, 4]\n",
    "\n",
    "pad_mask_squeezed = pad_mask.squeeze(1)  # Remove singleton dimension, resulting in [2, 4]\n",
    "\n",
    "pos_encoding = torch.tensor([\n",
    "    [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],  # Batch 0\n",
    "    [[13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24]]  # Batch 1\n",
    "], dtype=torch.float32)  # [2, 4, 3]\n",
    "\n",
    "# Create a mask of the same shape as pos_encoding\n",
    "mask = pad_mask_squeezed.unsqueeze(-1).expand_as(pos_encoding).bool()\n",
    "\n",
    "# Apply the mask: Set masked positions to 0\n",
    "pos_encoding_with_mask = pos_encoding.clone()  # Clone to avoid modifying the original\n",
    "pos_encoding_with_mask[mask] = 0\n",
    "\n",
    "print(\"Shape of pos_encoding_with_mask:\", pos_encoding_with_mask.shape)\n",
    "print(\"Content of pos_encoding_with_mask:\\n\", pos_encoding_with_mask)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "布尔读写逻辑"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The shape is pad_mask_squeezed: torch.Size([2, 4]) The content: tensor([[False,  True, False,  True],\n",
      "        [ True, False,  True, False]])\n",
      "The shape is pos_encoding: torch.Size([2, 4, 3]) The content: tensor([[[ 1.,  2.,  3.],\n",
      "         [ 0.,  0.,  0.],\n",
      "         [ 7.,  8.,  9.],\n",
      "         [ 0.,  0.,  0.]],\n",
      "\n",
      "        [[ 0.,  0.,  0.],\n",
      "         [16., 17., 18.],\n",
      "         [ 0.,  0.,  0.],\n",
      "         [22., 23., 24.]]])\n"
     ]
    }
   ],
   "source": [
    "# 生成掩码张量\n",
    "pad_mask = torch.tensor([\n",
    "    [[False, True, False, True]],  # 对应第一个批次的掩码\n",
    "    [[True, False, True, False]]  # 对应第二个批次的掩码\n",
    "], dtype=torch.bool)  # [2, 1, 4]\n",
    "\n",
    "# 去除维度 1\n",
    "pad_mask_squeezed = pad_mask.squeeze(1)\n",
    "print(\"The shape is pad_mask_squeezed:\", pad_mask_squeezed.shape, \"The content:\", pad_mask_squeezed)\n",
    "\n",
    "# 生成位置编码张量\n",
    "pos_encoding = torch.tensor([\n",
    "    [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],  # 第一个批次\n",
    "    [[13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24]]  # 第二个批次\n",
    "], dtype=torch.float32)  # [2, 4, 3]\n",
    "\n",
    "# 选择填充位置\n",
    "# 将填充位置的编码置为 0\n",
    "pos_encoding[pad_mask_squeezed] = 0\n",
    "\n",
    "print(\"The shape is pos_encoding:\", pos_encoding.shape, \"The content:\", pos_encoding)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The tensor shape torch.Size([3, 3])\n",
      "The index shape torch.Size([2])\n",
      "The sub_tensor shape torch.Size([2, 3])\n",
      "tensor([6, 7, 8, 9])\n"
     ]
    }
   ],
   "source": [
    "tensor = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "print(\"The tensor shape\", tensor.size())\n",
    "# 使用整数张量作为索引，选择第0行和第2行的所有列\n",
    "index = torch.tensor([0, 2])\n",
    "print(\"The index shape\", index.shape)\n",
    "sub_tensor = tensor[index, :]\n",
    "print(\"The sub_tensor shape\", sub_tensor.shape)  # 输出: tensor([[1, 2, 3], [7, 8, 9]])\n",
    "\n",
    "# 使用布尔张量作为索引，选择满足条件的元素\n",
    "mask = tensor > 5\n",
    "sub_tensor = tensor[mask]\n",
    "print(sub_tensor)  # 输出: tensor([6, 7, 8, 9])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 随机数据测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_get_angles():\n",
    "    position_encoder = PositionalEncoder()\n",
    "    # 定义测试参数\n",
    "    position_length = 5  # 序列长度为5\n",
    "    d_model = 8  # 位置编码的维度为8\n",
    "\n",
    "    # 创建位置索引数组pos和维度索引数组i\n",
    "    pos = np.arange(position_length)[:, np.newaxis]  # [5, 1]\n",
    "    i = np.arange(d_model)[np.newaxis, :]  # [1, 8]\n",
    "\n",
    "    # 调用get_angles函数\n",
    "    angles = position_encoder.get_angles(pos, i, d_model)\n",
    "\n",
    "    # 打印结果\n",
    "    print(\"Angles:\", angles,\"The Angles shape:\", angles.shape)\n",
    "    position_encoder.draw_pos_encoding()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Angles: [[0.e+00 0.e+00 0.e+00 0.e+00 0.e+00 0.e+00 0.e+00 0.e+00]\n",
      " [1.e+00 1.e+00 1.e-01 1.e-01 1.e-02 1.e-02 1.e-03 1.e-03]\n",
      " [2.e+00 2.e+00 2.e-01 2.e-01 2.e-02 2.e-02 2.e-03 2.e-03]\n",
      " [3.e+00 3.e+00 3.e-01 3.e-01 3.e-02 3.e-02 3.e-03 3.e-03]\n",
      " [4.e+00 4.e+00 4.e-01 4.e-01 4.e-02 4.e-02 4.e-03 4.e-03]] The Angles shape: (5, 8)\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAG2CAYAAAC3VWZSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADAOklEQVR4nOzdd3wUdf7H8deUnd1NspteIfQuqDRpAirFXk6xi72ip8h5Kqee6Nl/d4rt9LzTQ88Cd2IXCyqCCnh06b2EkEp6snVmf39sdtmEIJDgRc3n+XjMI5PZ78zOkrD7zXfm/fkqoVAohBBCCCHEL4Ta2icghBBCCHE4pPMihBBCiF8U6bwIIYQQ4hdFOi9CCCGE+EWRzosQQgghflGk8yKEEEKIXxTpvAghhBDiF0U6L0IIIYT4RZHOixBCCCF+UaTzIoQQQohflFbtvEybNg1FURosWVlZ0cdDoRDTpk0jJycHp9PJCSecwNq1a1vxjIUQQohfpgULFnDmmWeSk5ODoii89957B91n/vz5DBw4EIfDQZcuXXjxxRf3azN79mz69OmD3W6nT58+vPvuuz/B2TfU6iMvRx11FAUFBdFl9erV0ceeeOIJnnzySZ577jmWLFlCVlYW48aNo7q6uhXPWAghhPjlqa2t5ZhjjuG55547pPbbt2/ntNNOY+TIkaxYsYI//OEP3HrrrcyePTvaZtGiRVx44YVMnDiRVatWMXHiRC644AK+//77n+plAKC05sSM06ZN47333mPlypX7PRYKhcjJyWHy5MncddddAPh8PjIzM3n88ce54YYb/sdnK4QQQvw6KIrCu+++yznnnHPANnfddRcffPAB69evj2678cYbWbVqFYsWLQLgwgsvpKqqik8++STa5pRTTiE5OZm33nrrJzt//Sc78iHavHkzOTk52O12hgwZwiOPPEKXLl3Yvn07hYWFjB8/PtrWbrczevRoFi5ceMDOi8/nw+fzRb+3LIuysjJSU1NRFOUnfz1CCCF+uUKhENXV1eTk5KCqP93FCa/Xi9/vb/FxQqHQfp9tdrsdu93e4mMvWrSowWcwwMknn8zLL79MIBDAZrOxaNEibr/99v3aTJ8+vcXP/2NatfMyZMgQXnvtNXr06EFRUREPPfQQw4cPZ+3atRQWFgKQmZnZYJ/MzEx27tx5wGM++uijPPDAAz/peQshhPh1y8vLo3379j/Jsb1eL05XCgQ9LT5WQkICNTU1Dbbdf//9TJs2rcXHLiwsbPIzOBgMUlpaSnZ29gHbRD7Dfyqtes/LqaeeynnnnUe/fv0YO3YsH3/8MQCvvvpqtE3jHmVTvcxYU6dOpbKyMrrs2rULgJe/XM5NageM/ldRtuQTHINu4PdGJ17+dj3bHr+ZTle9xqLzx9Hl2tfZ8497SDzxLq4il5Jt67hF60iXa1/n23PGcu/7y9i1pxC936U8m9SNh+O7sO3xmyndtIKek2by5ZiRGP2v4taZi0k9/WEK33oc18gpPDdvDfc7u7D7xbu5296ZZ75czVR7Z5JPvh/7wGv5YvV2jn90DoVFRej9LmXJxNPInfgK//xuA7doHdn79b/5oM8Ayld8yQ1KB/6+YB3db3qLr08+AaP/VTgG3cAHy7fSc9JMnvpyNe7Rd1Cctx2936Ukn3w/b3fqx5BpH/LW95vCr2v7Bh6M68JnQ4YyZ+Bgdj17B6WbV3EVuXy9dic3KB2YntiN3rf+m7kjh7PjL5Mx+l9F+cp56P0uJWHEbfx9wTraXfw3Bt7zHj0nzeTWmYv5YPlWHINuYGd+AXq/S7EdczmFbzyCa+QUss9/ls+HD+Ooyf/h9fSePBjXhXvfX8YtWkeuIpd12/PD57ZzC2VLPuFue2cK33qcjX+8llmZvfn+wpP5ZNBxfH/hyczK7M36u69kzz/u4V5HF0rmvkbZD99wbf3+V5HLVeSyfMturiWXW7SO/H3BOn5vdOLe95dxxT+/YXpiN8Y++TnH3f8Bs7scTb/fvc0ng45jwWknkjvxFZZMPI01t19CyqkPsvWRm0g88S4SRtxG0X/+gnPITdgHXkvZkk+wHXM5er9LKd28Cr3fpRTnbaegMPxz3L67gDXb87EdczlLt+RFf1Yfr9iGc8hNJIy4jZe/XY979B088+VqHv5kBckn38/Ud5cy6c1FZJz9BFf88xuyz3+Wdhf/jdOe+YLcia/Q+Zp/MeKRj+l6/Rv0nDSTQfe9T+9b/03/u9+h3+/e5ti7ZnPU5P/Q65ZZHHf/B3S/6S2GPvghIx75mM7X/IvRT3zK2Cc/p/2lf+e0Z76g3cV/I+eCv3LBS/PIOm86mb/5C1e/+i0ZZz/BDa8vjP4+3/H2f5n67lKST76f+z9czoMfLydpzFQe+2wliSfeReKJd0V//1wjp/DC12txjZzC3xes4+Vv15Mw4jZeW7iB1xdtJH7YLbz1/SacQ27COeQmZi/dgnPITdHf5ci/0ycrt2MfeC2f/7CdL1aH179as4Ov1+7E6H8V36wPfzX6X8XCjbui64s3hv+9v9+Ux5LNedGfwdIt4fXlW3ZjO+by8PrWfesrt4XXV23bzer6n93q7fms2Z6P3u9S1mzPZ139euSr3u9S1u/YE13fuHNP9OumXeH1Tbv2rW/Zta9t7PrWvILo18j69t0FbN/d9Hpkv9j1yP+9nfkFB1yPtI28l8Wu79pTGF3fXVDI7oKm1yP7NbWeX1BI/gHWI22bWm/cNvL/qKCwqMF6ZL+m1hu3Pdz9tD4XAOByuY70R16U3++HoAe9zwXR82jW0ucCampqyMvLa/C5N3Xq1CN2rk19Bjfefrif00dCq182ihUfH0+/fv3YvHlz9DpcYWEh2dnZ0TbFxcX79fJiHWi4LC4hAbuiomgG7oR4FN3ArqjEJbhwOeyoRhwJNhuqEYc7zoGiBzBQcbtc2BW1/nEdR3wCbrcbRTNwKhp+RcHlsON2udDscSToOopmYI9LQLU5cMfpKLodZ4ILh6LidtqxK2r0e9XmQNEM4l1udEd89NgJhg2VOOISws/vTogjXtNwuxIw6s9bs4fPSdEMFN0gvv4cnPEuFN0ePZZqcxCvauiOeOISXOHX5XbhUDTidR0zpOB22olzhR9LcLkxFBWnoqHZ44jXddxOe/jfzpVQ/3x24hJcqIYT3RGPZlexxyUQ73Kh6Eb0uRVVq//3tKPanMTrOpo9jjhVw6FYqPHhn0sAcLnd0XPT6uLDrzvOgeUwiFM1EgwbPl0nwbARp2q4HAbuOEf43zU+Dq3+38btDr8OIPpaIj9ru6LiiE/A8IZfn80Zj+7TiNf2vdYEmx7+eWMjzh7+93M57Ci6HcUK4Y5zhtdDSvh3STNAMXG7XOF/I7cb0xaHohm43G7UgBX+mbrcDX5Wim5H0Q3iElzR35GAL4hqc+CIT8CrBFBtToy4BFSbE9VmYHPGoxpxqIYt/O9u+NFsGrojDs2roTlshFQTTVexMEGzwo/ZQ+H2uopqeNGd8dj08O91+JhOQqaJ4Qw/V8gyo89rj0vArod/V+1xCRj16474BDRVQdEdOOp/54Do7x+WhbP+tcUluFBVZd+6sm89sl98ZF0xo79H8a76tlrD9QSXu8G6ohnRn3fj9XBbouvAfvu5mlh3xTyHy+VGqT+Gy+1GZd96dL8m1l3uhvtxGPvFtm1q3R2zX1Pr7kZtj8R+/+vnjvz7/2+f2xb++j+4zUCpf/9vrpCqAeHXEDn/IykrK2u/EZTi4mJ0XSc1NfVH2/zY5/SR0Oppo1g+n4/169eTnZ1N586dycrKYu7cudHH/X4/8+fPZ/jw4a14lkIIIUTLKarW4uWnNGzYsAafwQCff/45gwYNwmaz/Wibn/pzulVHXu644w7OPPNMOnToQHFxMQ899BBVVVVcccUVKIrC5MmTeeSRR+jevTvdu3fnkUceIS4ujksuuaQ1T1sIIYRosRZ3QEKHt29NTQ1btmyJfr99+3ZWrlxJSkoKHTp0YOrUqeTn5/Paa68B4WTRc889x5QpU7juuutYtGgRL7/8coMU0W233caoUaN4/PHHOfvss3n//ff54osv+Pbbb5v/ug5Bq3Zedu/ezcUXX0xpaSnp6ekMHTqUxYsX07FjRwDuvPNOPB4PkyZNory8nCFDhvD555//pNcihRBCiF+jpUuXcuKJJ0a/nzJlCgBXXHEFM2bMoKCgIHqfKEDnzp2ZM2cOt99+O88//zw5OTk888wznHfeedE2w4cPZ+bMmdx7773cd999dO3alVmzZjFkyJCf9LW0audl5syZP/q4oihMmzbtiNw1LYQQQvycKEoLR16sw9v3hBNO4MdKu82YMWO/baNHj2b58uU/etwJEyYwYcKEwzqXlvpZ3bArhBBCtBWKpqJoLbls9LO6bfV/qs288vYP3cjpPdPofPxpHP+On+xjRpPrtHH8O9P4eMRkdi/5FPtTM5n3p3FMv+ZV/vTAlVxxYke+G3ceaYbGzoUf0uO1d3lq+jsU3zGR7P5jWVLu5dL7TmbmfR/x0KoAW+Z/wMAX/kzXkafzpxPbU7FjDQvumEG/k8cxsX2A08/qzoJ73qHQG+Tpt9cwblg7qnZvIuuYE7nn/bVMO7MPoY+fIy41hyXvbWT4qC6c3SWewckOtv/jnyzaUs6OxN6YoRB/n7+NwrXL6HXJaKygn6QOvXntv3kMGJDNKd1Sqdu7B5Z/gi0+kfRufVhXXMv4ATkMbeci0abC2gX0dtvJGdqJnVvLSRhyIqX2DAAW7S4n067TMT2O8vxCsgZ0IP7oAVhBP4HMnmiGE0dyJkt3VZCYkULH9m6qSvbSr10inZMcmH4Pcd4yAHRnAtVbdmBPTCM+JZWq3dW4kp0Uek2qgiZd0+LxmBYAqXE6mgJadRHBwl3Eayq+wkLqCvfiSHZQU1xLQmY8zowkyv1B4rNT0VKzqTUttOQMrLgkzBAE7fvuuq/ymWiKgqEqlHkDOFSVvTV+Kuv8JOgqdZ4Afl8QI95GwGdiT7Rji7dh+jwYrjhs7jisgB/DHY8VDBCyTJQ4N1bAH143wskcgJDhDH/V7fjrX5PfDBG0Qiiqht8MRf/K8gYt1Prr3b6ghaJqeE0Lj99EUTU8fhN/0ELVDfz1jyuqhj9ooek6iqIQskKouoqiKlhBC00Pfw2FQuFtVoiQFY4sWkELVVXQNJWQFUJTFTQ1nKbQVIWQaYYTRrpGyKpf11RCloldV8NtLDO6X8g09zsGEG4TE9JQlfB+qqpE12Pbq40jlmb948q+xzV137Ga2n4gkUOrjUIjKvunSGLbNH40cs7/a43PO6KlGZifMkVzJI/c+HdDiFgy8iKEEEK0ArWFN+yGfuK00c+ZdF6EEEKIVtDitFEb7ry0mctGQgghhPh1kJEXIYQQohXIyEvzSedFCCGEaAWKqqK0ZObqn3DW65+7tvvKhRBCCPGL1GY6L698uJmu879i1T0DWPafN1j15Glcs3IWj/5pLrf+/gVOvekaxtz5HntvPB+vZXHN3jkM+PAjZq0sYtJzF9P5+LMY/+wiagp38M9XVvDk7SdwTpdkgtc9xpoqHy/94wucyZn8oziVR68dTPFjU0jrMZiPt5bzwuUD2PnQVI760x/5bE81g5MdbFv4BQP+eD1xqTmcdWpP1s5fzghHCSuf+YCOg4azpNzL3WN7YH7yN449pxer3llPnifA6yv20DXeYOvKndSW5GGcdCnO5Cw69OvO0uV7uGRQLu28eSiqRtFnX5CU25tuvdPJ8wQ4tWcGqVXb6BRnUDp/Pu2OyyZr1GC21gYIdhzID0W1JNpU5q0vpnO8jaxjM6kp2k7m4D6oXfqjqBp5deBITMOV2ZFVO8tJzU6gf8dk6vbm0yc9gex4PRyXLd2OqhsYcW4qt+bjTM7CleKkrMpHu8x4yvwmNUGLTklOzPqaSXp1MYaqECrNxyzaRYqhUpNfQk1BJfGZcdQW1RKXkUBcRhKVAQt7Rjp6ahZ+K0QoIQXLmQRAjT8St4VybwBDDUelS6p8ODWFslo/e2vCUWmfJ4jfE8TutuPzBDDibdjdTky/B8Mdj+GKwwr6sSXEE7JMzIAfNd4VjRNb9fFogJDuACCIir/+RfnNUDQi7Q+Gvyqahs+MxJ9VvPVR6Eg8OhKf9te38QdNFE2LiU0raLqKGQyFI8O6imla4Ui0FSJkgaapWEEL06yPUFshVE2NRqg1VcHQ90WhI6+nQeRZVbDqv0baNo5HRyPUMTFoVVUIWVb0ZwCRmPO+dSB87Jg0rHagbPBBxEZqG8egI+fUVOr2YEnc2OPGto190zxY7Ljxw0294f4vJgA83Odp5o/iiGhLEemf+9xGP2dy2UgIIYRoBeHLRi2556XNjD/sRzovQgghRCto8fQAStsdeWm73TYhhBBC/CLJyIsQQgjRGjStRXMbhQ5zYsZfE+m8CCGEEK2gpTfdtuUbduWykRBCCCF+UdpM52Xa9PM57poXebPnOC75/S1802coo97ay1ndUjBcycw+PkDx2u944T/rmfLU+bxw8dOc8PR/Oa9XKouG38LbfziRJf+exaAJFwJwRtFnjP33Q1z40n85p0sye7csZ/iE03j074s5LfAD7z/7LRddMpIEXaXH+vf5+LVVfBXqiqEqnHT1YIKeGvL7nkX3kaO484QulG1bReFLT7JgaQFXnN4TMxTiKN9WVr/0CV2uuZzFZR4SdJV3v97G4L7p7N2yHFU3WG+mkN5rEKcNyaVg3SpGdnDjWzCbuNQcts3dQE6vTkwY2B6PGeLoVB3f4k/o2cFN3vwNtB99FEb/EynxBdlep/LNtr3kOGzs2F5O+y5JZA3qhq+6HHu/YVQltMOIT2R1UQ1xqe1IzkygdE81vXOT6JvlxltVSq7bhl62A0XVCOxYjxGfiDM5i/LtZSQkuUhMjaPQG6R7pouqoInfCpEZbwPAUBW0qkISdJVg0S5q8gpJMTRq8kuoLQrPJl1X6iEuI5m4rFRqghZaajZqciZ+K4QVl4xXtQNQE7DQlPAxS+v8ODUFh6pE49F7a3zhWHScDX/9rNJ2t51gwMTutmNzxxP0h2eVjswmrcS7MYPhmaRVZ3w0WhyJRwNYtvB6g3h0/TpAXSAcedZ0IxqPVlQNb3DfTNIev4mmG3gCJh5/ENVm4KufXVpVFcyghVYfeTZNq35WacIzResqlhnCrI9TW6H6WaVVhVAohBoTeTZ0FT1mdujYqHQkXqw3ikTHrjeOTUfirSHLis78HJlNOiLSRqufYTpWyDQbxHMjM1Brasx+ihJzjH3bm0rWhiyzybhvUzNKHykHixcfzpvt4c4ofSSjza0Zk25t/+uUtkSlm08uGwkhhBCtQFU1VJkeoFnazMiLEEIIIX4dZORFCCGEaAUtLVLXonmRfuGk8yKEEEK0AkkbNV/b7bYJIYQQ4hdJRl6EEEKIViAjL80nnRchhBCiFUjnpfnazGWju+PPRlE1dtUF+Kv9Kz7fXcWSWa8zctVC3n/6amYMv45Lf3cD53RJ5pvRkynyBVn2nzc4Yd6/uebBD8l844+42/fg41uGctXV/Xnvkv/jDY5m+XvvMubN+8kZeDKvXnIse5Z9xqIbH2BNlY9Hx+Ry5oj2LPzd86yv9nHPWys5rXca7e+YRnqvodw7ZwO//01f0lbMxu5KYflLi9hRF+CaATkMSHKw5+Xn+W5xPuW9xlETtBic7CDvh1X0uXQ4gdpK3O17MGNJHr2PzeaCo7OpKdqBY/1XbPtgIandjmHN5jJGHpvDiZ2TSdBVtA0LyP/qv3QY1Ykdq4pIGj6aiqSumCFYmFfBtxuK6ZZopySvhJzB7UkaMADT7yHY/mi2V/hxJGeyLK8Cd1YW2e3cVBRXMLBDEj1T4wh6akgK1RLavRHNcFKzaSOGK5m41Ewqd1biTouja5aLqqBFz0wXHjOEGYK0OB1NAaemECzcgVvX8OXvoia/hIRkBzV7qqktriUuw02lN0hcVgq2jBxqTQstNQszLjlc58WZTLUvXJ+kxh+uNWKoCuWeADZFIUFXKav14dQUauoCeOsC2N0GPk+QgC+IkWAj6KnBcMdhuOIwfR4MdzxafAJW0I8a5yJkhmuhKE5X9PcqZDij65F6Ln4rhN/aV+elLhCu4+IzLdT6NytPwETVbai6gcdvotoM/EGLOn+4rT9o4a+vBROu/aKjaiqWGa7homkqVtBCrV8367dbVri2i6aphKwQVsy6rqv71WgJr4ffBkKWiVZfX8WKqfkSbWuG68PE1nyxqWr9fvv+r0VqtMSuawoNasJE2qtK+LhAtD5M+NjEtI3ZTyV67KY0VadDURrWd2myTcx67PnHto19s1QOUhCkufVCDre+y6E62Pm26NhH8FiN6//8L7XGU0cmZmz2IhMzCiGEEEL8MshlIyGEEKIVKC2cmLEl+/7SSedFCCGEaAVS56X52u4rF0IIIcQvkoy8CCGEEK1A0kbNJ50XIYQQohVI56X52sxlo/888xJLX76eP3z7NH+86K/c/9eLGXLJRPrf+SkZf76J9dV+Xuy8kzGL3uXae95kykOnk91/LGe/V0TJhsW8eN/H/Onu8yi8/VIy/vwv5pXUce/0L9FsBu86j+OBm4YTemkqSZ368s6SPQxOdlD82BQG/2UqH6wupq/bzvqvvmDYI1fwnwI7Y0/vz/xPVvCbLD+r//wqHQaNZl5JLel2Dfv8GQw7ozurXvkvm2r8vP5DIZ3ibBxzVg+q92wl8TdX40hMp8PRR/Hlol1cOawjXUMlhCyToo8+YPvXu+jUJ4OttX5+0y+bHG8+neJslM37nJ0LdpJz4nFsrPYT6jmcVUW1JOgqX6wronBHBTkDs6jes4WsYX3Reg9FUTX2+G0s3VNJQmZnFm/dS1qOi8GdU6gt2UXfTBftXDZCloleug3/tjXYXclUbMojLrUdrmQnZXs95GQlcFQ7N5UBk05JTvxWOFZsr9uLoSrEayrBPTtItKnU7C6htrCC+Ix4aorrqCn3EpeVSmXAwpmdiZaahccMgSsVKy4ZgOpAiJqAhaZAca0fQ1Vwaiol1T4SdBWnprC3xk+CruKtC4Tj0fEGAV+QgNeLIykO0+/BcMVjuOOwgn5srjjUeDdmwI8a78YK+glZJiHDGY3Shmxx0d+xSFTaFwxF171BC1/QQtG0aGRaUVW89TFoRQtHoRVVo85v4jet+vh0EF8wvB6OTCtouooZDEefNV3FCoVQNQVFVQhZROPT4dg0mEGLUCgUjVDHxqPtuoqha4SscPw58noMXcWyzGhEOjYqDTSMWMdGnlWFkGWF28RETmMj0UA4gq3s+15rIhv8Y1HoCFVRotFWtVFYt6mYc0SD6HMTj8c+d3Nj0vudaxPbfsrocnOf50Ax7f+F1oxIi18mGXkRQgghWoGqKqgt6TW2Zo+zlUnnRQghhGgFihoeOW3J/m1Vm7lsJIQQQohfBxl5EUIIIVqBoigtuv/pf3Xv1M+RjLwIIYQQrUCpv+eluUtzLxv99a9/pXPnzjgcDgYOHMg333xzwLZXXnlltJMVuxx11FHRNjNmzGiyjdfrbdb5HQrpvAghhBCtQFGU6H0vzVqaMfIya9YsJk+ezD333MOKFSsYOXIkp556Krt27Wqy/dNPP01BQUF0ycvLIyUlhfPPP79BO7fb3aBdQUEBDoejWf8uh6LNdF5OveFqNo4YzZiv4xnTzsXzXa9k/nkudi7+lKf++l/ueuJs/jruLk56dTs1hTvYcN79vPPAaXz18mv0/82F1JoWV/kX8cqMlZz14vec3TGRojULGHLBOdz13EIui9/B7Ic+44LLxmKoCmfcPY73n/2W79yD0BSF064eiLeyhOJhV/DEf37gwVN6ULJhMSUvPc4X83dx5dm98VshRndN4Ydn/kO3m67km9JwjPmNzzczvG86Xa64CEXV2Ki2I73XcZw+vCP5a39gfNdkAvP/TVxqDps//IHlFV4uGdoBjxlicJYD/6IP6dXezY4vVrNhdxX2QeMo8gXZ7nfw1eZSchw6GzfvpWL3DrKGdMdbWYqz/yhqEjuiOxNYXVzLoq17Sc12UbK7ir6dUzi2XSKe8iI6JdkxyneGZ0Le8gPlG3biTM6ibEsprpQkUjITKPSa9M520zUlHr8Vor3bAMBQFfSqQhJ0lUSbRu3uAtLtGtV5RVTvqcGVk4CntI4yv0lCu3QqAyZaajZaag5+K4QZn4pXC8/qXO03KfMEMFSF0jo/Tk3BoSoUV/lwaioJukpdrR9nvIHfE8DnCWJ3G/h9QYKeGmzueIJ+D/akBOxJLqxgANWVjBrvJmSZqPGucEzaMrFi4tEh3R5d99XHn/1mOCqtqOF4dF3ARNONffFoVcMbDMejI7NKa7qBJ2Di8QdRbQa+oBWebVpVMIMWmqaiqAqmaaHqKooKVtBC09XwrNL1cWorVD+rtK4SCoUwg1Y0Cm3oKnZdJWQ2nlVaib42PeYvOUMPvz00bhs7O3QkIh2Z+TlkmdH0RMgyG0SiY+OwkVmq1QbR5YazUUN4pul9x9i3/UDv2U39Ido4Sn0k73E82LGOxBvsgZ6iDd+reUS1tSsvTz75JNdccw3XXnstvXv3Zvr06eTm5vLCCy802T4xMZGsrKzosnTpUsrLy7nqqqsatFMUpUG7rKysn/R1tJnOixBCCPFz0qJRl5jLRlVVVQ0Wn8/X5PP5/X6WLVvG+PHjG2wfP348CxcuPKRzfvnllxk7diwdO3ZssL2mpoaOHTvSvn17zjjjDFasWNGMf5FDJ50XIYQQohWo9SOLLVkAcnNzSUxMjC6PPvpok89XWlqKaZpkZmY22J6ZmUlhYeFBz7egoIBPPvmEa6+9tsH2Xr16MWPGDD744APeeustHA4HI0aMYPPmzc38lzk4SRsJIYQQv2B5eXm43e7o93a7/Uda759SCoVCh3T/zIwZM0hKSuKcc85psH3o0KEMHTo0+v2IESMYMGAAzz77LM8888whvILDJ50XIYQQohUcqSJ1bre7QeflQNLS0tA0bb9RluLi4v1GYxoLhUK88sorTJw4EcMwfrStqqoMHjz4Jx15kctGQgghRCs4Uve8HCrDMBg4cCBz585tsH3u3LkMHz78R/edP38+W7Zs4Zprrjno84RCIVauXEl2dvZhnd/hkJEXIYQQoo2YMmUKEydOZNCgQQwbNoyXXnqJXbt2ceONNwIwdepU8vPzee211xrs9/LLLzNkyBD69u273zEfeOABhg4dSvfu3amqquKZZ55h5cqVPP/88z/Z65DOixBCCNEKWjoxY6gZ+1544YXs3buXBx98kIKCAvr27cucOXOi6aGCgoL9ar5UVlYye/Zsnn766SaPWVFRwfXXX09hYSGJiYn079+fBQsWcNxxxx3+izpEbeay0YvGF8zZXMai119j2JpF/OnuJ/nbgMu44Q83c07PVOaN+T1FviDfv/kvLvjtlVxy7ztkvzqVpA69+WLKCG64eShvn/sg8ZrKkrffYdy7j5M75HTevnIA+Uvm8N0Vd7Gq0stfxrXn3NEdibvlCdZU+fjda8s445hMcqc+QmbfUUx5fy1bv/2KjKWzsLtSWPjsAnbUBbhpcDsGJzsZdNs45n+7m729T6EyYDE0xcmOZcs4+poT8Aw4m6QOvXlp8U76DWrHJf1zqN6zFcfauWyevYD0ngNZs7mMQm+Q8V1SSNBVtLVfkvfZQjqd2JntywvZURegIqU7Zgi+2VHON+uK6J3qpCSvhNqSPFKGDMH0ewi2P5rNZT7iUnNYtL2MDdvKaJ+bSHnhXgZ3SqZ3WjxBTw0pVjWhvPVohpOaTRsp35RPXGomlTsrScqIp0eOm1J/kJ6ZLjonOTFDkB6noyng1BSCBdtw61q4vsuuIhKSHdTsqaa2uJb4rCTKawNUBixsGTnUmhZ6RjvMuGT8VgjLmUy1L1wXpMpnUloXrvNS7gngUMO1XUqqvSToCgl2HW9dALvbwOcJEvAFcSQ7CHpqMP0eDFccps+D4Y5Hi0/ACvpR41yoCUmELBPF6Yr+LoUMZ3TdZ4W/KqqG3wpF67zUBcJ1XHymFV33BExU3Rat7aLaDFRVo85f/7jfxF9fC8bjNwkGLVRNxaqv7aJpKlbQQlWVcG0XM1zbRdXVcG0XLfzVilmPrePSsF6Lum+9vr6K1ajmS6QWi6Gr0doumqpgU9X6/YjWd2lcoyWyHlsTRqt/n21Q76VB7Rf2264qCppK9HixIvVbIodo3Ca2vosSfe59j8e+7ceec+x9i7FvkLE3NDb1mXEo9UKauinyQJ8/LS0/8lOWjm9jpVF+Mora8qU5Jk2axI4dO/D5fCxbtoxRo0ZFH5sxYwZff/11g/aJiYnU1dVx3XXXNXm8p556ip07d+Lz+SguLuazzz5j2LBhzTu5Q9RmOi9CCCGE+HWQy0ZCCCFEK5CJGZtPOi9CCCFEK1BVWnjPyxE8mV8Y6bwIIYQQreBI1Xlpi9pwv00IIYQQv0Qy8iKEEEK0AkVp4chLG77npc2MvNx//es88t4dnPnbGzj6ltl0HHoKRb4gj9kWMHLZAm688x9M/ftEOh9/Fq8M8rB3y3Ke+9PnvPDABWy+5GyM+15iQWkd19w9BiPezcv+3jx92/FUPXwz6b2G8vbSAk5MjyPvDzcy+IVHmfzBBgYnO1j/5acM+/MtvLJd4dxzB/Ldx4vx11ay/OFX6TL8JBaU1pHj0FE/fpYRFxxF3Pm3srXWz4vf59EjweDY84+iumAr8Wdfx+z1JXTqfxRffreTG47vTFd/HgAF77zL5vm76HVMFltr/WgKZNdup2u8Qclnn7Dj6x20G38866v91AQtlu6pIdGm8smaQvZsKyfnuByqdm/EV12G1nsYiqqR57PxfX4F7uwuLN5cSumeKoZ2TaW2eBfHZLrJdenhuGzRZnxbfsDuSqZ8/U72bi4nKT2eklIP7bMSOKqdm5qgRffUODLiw31le20JhqoQr6kEd28lxVBJjrdRnV9OQnYC1QU11JR7ic9OpcxvUhW00NPb4TFDhNzpWPGpAFT5Lar8FpoCpXUBSuv8ODWVwkovTk0hQVfZW+Mn0aZhd9vxe4LY3XZ8ngABrxe72xmOhfs92JPC8Wgj0YXqSsYM+FFdSajxrnCM2B4fjdKGbHHR3ytf0Iqu+81wVNobrI9Haxp1ARNf0EJRVbz1MWhFC0ehFVVD1Q38phX+GjSp85v16xamaaHpKmYwFI4M6+F4tKpF4tGgaSqqqtS3VTCDFlZ9hNqqj0obejjabNdVDF2LbjM0Nbpu1cejI21DptkgHh0bq45GntV9E8NpMe+hWqP3U6s+Vh1tqyr7xYObikI3pirKvshzo7BuUzHniMbbGjc50HMfKCZ9KJp6Yz1SHzQH+6w7nOc53M/NI/lRqbbhD96IIzUxY1vUZjovQgghhPh1kMtGQgghRGto4Q27hz109isinRchhBCiFUjaqPnkspEQQgghflFk5EUIIYRoBS2dmLEl+/7SSedFCCGEaAUyPUDzyWUjIYQQQvyitJnOy8VjOnHBngG8kbOKih1r+OGxMdz97p08MuFJBv1xHlbQz5s9r+LrP43jP8dfxyk3XIlbVxm7/G/844NNnPmXb7h0aDt8N/+ZC66fwANPzmFc/hz+9fS33HnLWNIMjTOevoRZr6xgZnV7Ppw1jzPuHofp87Cxxxk8+foKHhzfjbJtq8jsN4rP/7uHKef3Q1NgzMBslv75Pbrcdhsf54dIMTRmz93CiKHt6HTdtWiGkyUeNy9/sYWLT+xC/g9LOKm9g5o5b5CQ2YmN7/3A8govE4d2xGOGyHXaqJs3m6N6prD90zX8sKcG2+BTKfQGMVSFOeuK6BRnsGXTXip2b6Hd8X3wVpYCUBaXg92VwtI9VXyzsYS0HDclu6uoKtjBoPZJeMqL6JRkYCvdgqJq+DetoPSHrcSltqN0Ywnlu6tIzUwg3xPkqHaJdE+Jx2OGyHEZJIbqMFQFrTyPRJtGiqFRvXMP6XadhOwEqvKqcGUnUFtUR4nPJCE3k8qAhce0UFKy8ZgWVnwqHsUAwnVe9tYFMFSF4hofxdU+4jWV4mofCbpKgq7irQ1gdxnY3QY+TwC7207A5yfoqcGe5CLgrcH0ebAnuzD93ga1XdR4NyF7QrjuSUxtF8vmiK5HartE6rsoari2S13AQtON+vVw7ZZafxDVZqDqBh6/iaYbKKqGp357nd/EH4zUdrEwgxaaVl/bRVdRVAhZITRdRVXCNV00XUXVFEJWCEVVCIVCWFZoX70Wy0RXlWjdlmi9lvp1AD1m6FlrtB5pa2jhtwpVCQ9zhywrWvMlZJnR4euQZUZrT1gx66pS/9ymiaqAFrM9UmcltmZFZLum7tu+X72WyHMf4I/P2PYHr40S0/bHmx5+bZRm/HV8oD3a8FWCI+rnMmChqC1f2iq5bCSEEEK0Arnnpfmk8yKEEEK0AolKN9/PZtDp0UcfRVEUJk+eHN0WCoWYNm0aOTk5OJ1OTjjhBNauXdt6JymEEEKIVvez6LwsWbKEl156iaOPPrrB9ieeeIInn3yS5557jiVLlpCVlcW4ceOorq5upTMVQgghjoxI2qglS1vV6p2XmpoaLr30Uv7+97+TnJwc3R4KhZg+fTr33HMP5557Ln379uXVV1+lrq6ON998sxXPWAghhGi5yD0vLVnaqlbvvNx8882cfvrpjB07tsH27du3U1hYyPjx46Pb7HY7o0ePZuHChQc8ns/no6qqqsEihBBCiF+PVu28zJw5k+XLl/Poo4/u91hhYSEAmZmZDbZnZmZGH2vKo48+SmJiYnTJzc0FoPr/ZvDZC3/n/rMe480XpjC3+3BurxlCrtPGpi/f4enHb+DOqX+j8MrfsKC0jtnjnNzy0kSeufENBiQ5WDvnPwx9/w1+8+dveH50IqWbljDnsj9T5Avy2+wyLrlmAHvG3MYeb4D7/7GEih1riL/lCToNP5WbXlvGzsWfwsyHScjsxFlnHkOhN8jFHRXGZCQw4O6L+OqHYjYkHsNfPt7A6I6J5C1fyNG//Q357YeT1mMwf/lqC9uWreOCozKpLckj9O0s1s/8jpy+x7JsVxVlfpPxXZJIMTSOSY9j20ff0+WUo9iwroQ8T4A99mwAchw6368tons7FyXbd1JbnEfisNFYQT+6I4EfiuuIT8/l2y172bK1jB5dkinP34O3vIgeqU6C3hrcdUUEt/6AEZ9IxdqNlG8swJWRScW2imhEujxgclSWiy7JTgAynBpa+W4SdJXA7q24dZV0u0bV9gIS0uNw5SRQW1xHQvs0Sn1BKgMWeno7ak0LjxnCSkjDDIHfnkilzwKg3BOkuNaHU1MpqfNTUOElQVcprvKSaFOJd+p46/zY3XbsiXYCviDOZAdBTw0Bbw325ARMnwcrGEBzJWEG/ShxbtSEpHB81+kmZIQj0iHDGf0d8wXDz6+oGt6YqHRdwETRtGg8OrLNa1r1kejwNk0Px6JVPRybjqz7gxZ+v4miKAQDJsGAhaIqWEELTVeisWlNU1H18LqiKOFodf32kBWKxputoJ+QaUZj04au7VvXVOy6imWZDWLVkThzKGa7pir7osuNYs6Rv/xiI8+aqmBF1puIK2uK0iAKHaHFDIFHtquNhsVV9sWmm/qjU20iZBzbTmmwfd85H0jssHxTz9fcUfsDxrubd7gj8twH03b/xv/pKIoSvWm3WYtcNvrfy8vL47bbbuP111/H4XAcsF3jH04oFPrRH9jUqVOprKyMLnl5eUfsnIUQQogjJVJvqSVLW9VqUelly5ZRXFzMwIEDo9tM02TBggU899xzbNy4EQiPwGRnZ0fbFBcX7zcaE8tut2O323+6ExdCCCFEq2q1kZcxY8awevVqVq5cGV0GDRrEpZdeysqVK+nSpQtZWVnMnTs3uo/f72f+/PkMHz68tU5bCCGEOCLUFo66tOUbdltt5MXlctG3b98G2+Lj40lNTY1unzx5Mo888gjdu3ene/fuPPLII8TFxXHJJZe0xikLIYQQR0xLL/1Y0nn5ebrzzjvxeDxMmjSJ8vJyhgwZwueff47L5WrtUxNCCCFEK/lZdV6+/vrrBt8risK0adOYNm1aq5yPEEII8VORkZfma/U6L/8rF9/0Z8787Q0MTXHS7S838HVJLa88+hzXrJjJ2Buu5exlL6A74vnb+5u4+bJ+fDLsMj47+lpqTYvL3v4DmX1HcdFHRaz/7G2WX3Y1Pcacy2dFtZx/XA7fXXobuY/9nStfWcI5PVPZtXgOaT0Gc9sHG7jnioGs+fwLNLuTb6d9wDGnnMAD47txTKKD0hcf5rgpJ1E3+ioKvUEe/GwDGxcuZcBNo/GUF8L463lx8S76DOvOsoU7KN+xhvSd36EZTra9+SErlxcxekgueZ4ATk0hYeu3HJNop8v4rmyev4uMU05hU40fvxVi/o4Kshw6fRMdFGwrJndELjVFOwh6awh1H4qqG8Sl5fDNtr0kte/Ais2llOaXcXz3dGpLduGrLiNL8wKg7F5HzZqV2BPT2LtmB3s3l5OcmcCeKh+lfpNj2idSE7TokRZPVoKOpoBevguzIByR9u3cQrpdIyXVSdXuStztXbjaJ1NW5cOVm0GZ36QqaKJndcBjWvitEGZ8KgCVPotKn4mhKhTV+imu9eNQFQorvJRUe0nQFcqqfMTrGna3HZ8nHI92Jjvw11ZjT44nGJlJOsmFFfRjBf3heLRpormSolHpkOHEsscDEDLio79LsfFoXzA2Km2h1sejfUELVbfhC1rUeMOzRjeYSbp+pmnVFo5IK6qGz29imeGZoi0zVB+RbhSPDoZnj47EojU9HJcMWSF0XcUMBvfFnM1I/Hlf5FlTGs4qHY1HW2Z05unYyDMQnT0awKapDWLTsesR+80OXX/c2G1NRaEj643jy5EmKkqT0eRDSYsebkQ6fNwDx6Sbes6m3kwbJyOb+1lz8Fmxf7oPsSN55MbR9/+ln2OqWNJGzfezGnkRQggh2gpdBb0FHZBQmxl+2F8bfulCCCGE+CWSkRchhBCiFcg9L80nnRchhBCiFagt7LyYbbjzIpeNhBBCCPGLIiMvQgghRCvQFBVNbf4Ygqa03fGHtvvKhRBCiFbUWlHpv/71r3Tu3BmHw8HAgQP55ptvDtj266+/Ds9+3WjZsGFDg3azZ8+mT58+2O12+vTpw7vvvtuscztUbabz0u7YkbyespBTty9l+ssrmTbjSjoffwajZpbx4Qkmj94yk3/++Rp+0z2FhOlv8VFBNTdP+w+33DeeV+JG8dI9p/LpKzNJ7zWUN77awazfjWJsRjwjXn+K//x3Dzd8sJWVH33I6Jd+jzM5k4suGcmHs+ZxcUYl3soSuo8ax2d7qnnmwmNwznmasRf3ZeGzC0i69h6eWbiLHgkGC79cR+Wu9SRdehtxqTm88UMRH3y5lSljulOyYTEhy2T3m2+Q0uUYVn+6lfXVPq46rgMAvV12ij98lx7D29PhrDGsqfIR6jeWyoBFok3lvZX59EgwyD2+PZW71pE7ZjDeyhIUVWOn34kzOZPEdt1ZsL6YzA6JFO2qoKZwO4NyEvFWloZreRSsR9UNPGuXULZ2O/HpHSjdWEZxcS0dclwUek0qAyY90+LxWyGy4m04aoowVAWKthPctYl0u0bl1nzSEgwSshOo2l2Fq30irtxMyvwmce1zqApaeMwQoaQs/FYIgKpA+OdY6TMprvVjqArFtT4KK70k6CoFlV6Kq3wk2jS8dQEcyQ4cyQ68tX7sbgNHUhxBbw32JBdBvwfT78FIdGH6vZgBP6orKVzvxZWEZY+vr/MST8gWB0BA2TdI6QuGz0lRNbz1NVo0m0FdwIzWcIms1/iC0foudf762i66gccfrv0SXjej9VzMYAhNUzGDFqZpoWoKZtBC1VU0TY3WftH0+u2aGq4LY4X21WuxTOy6Gl036tcNTcXQVaz6xyPbNTVciwXA0MNvCeHaLeHj2ernUAlZVrhGS/37pa6p0fVI/Q6rUc2XyJurqoTrxRxMpP5K5HiKEq7v0riNqjRdtyN2W+R9vXGNlybbNjjGj5/nIdWVOYJFRY7UbQ3NOc6RehWtWd9FNDRr1iwmT57MPffcw4oVKxg5ciSnnnoqu3bt+tH9Nm7cSEFBQXTp3r179LFFixZx4YUXMnHiRFatWsXEiRO54IIL+P7773+y19FmOi9CCCHEz0lrjLw8+eSTXHPNNVx77bX07t2b6dOnk5ubywsvvPCj+2VkZJCVlRVdNE2LPjZ9+nTGjRvH1KlT6dWrF1OnTmXMmDFMnz79sM/vUEnnRQghhGgF/+vOi9/vZ9myZYwfP77B9vHjx7Nw4cIf3bd///5kZ2czZswY5s2b1+CxRYsW7XfMk08++aDHbAm5YVcIIYT4Bauqqmrwvd1ux26379eutLQU0zTJzMxssD0zM5PCwsImj52dnc1LL73EwIED8fl8/Otf/2LMmDF8/fXXjBo1CoDCwsLDOuaRIJ0XIYQQohWE5w1r/v1AkX1zc3MbbL///vt/dELjxvdkhUKhA96n1bNnT3r27Bn9ftiwYeTl5fHnP/852nk53GMeCdJ5EUIIIVpBS4vUqfX75uXl4Xa7o9ubGnUBSEtLQ9O0/UZEiouL9xs5+TFDhw7l9ddfj36flZXV4mMeLrnnRQghhGgFR+qeF7fb3WA5UOfFMAwGDhzI3LlzG2yfO3cuw4cPP+TzXrFiBdnZ2dHvhw0btt8xP//888M65uFqM52X72/vwR8mPEPv2z7mtiuP5kH3eax8bDxLZr3OS0Ovo1OcweD3/8SJCz9g3P1fcMPZPajcvYmCKx7lvodnMnrVK9gc8fzfnafRKc5GznuPcMart/HX4nQy7Tofvv4JIdPk2+wxDDn3VB4d25GKHWvY9Ie7aT/4FB68bABOTaHnji/4btrbdLnrXuaV1PLWVh8zP9rASeM7U7JhMbb4RL4oc5I7YBh/+2Qju1cu4sRMCNRW4m7fg/WzVtJtUA+WV3jxWyGOdlTRKc6g79EZbHpvJd3OHY4+5EwKvUF+KLNwagpd4w02riuh67GZdBzbH095EfYhpwLgSExn8e5K3O17ktEhicKdFQzrkU5l/lY85UV0S7FjBf0oqoZv7fc4EtMo/WErxauLSM5KojSvinxPkP4dkykPmHjMELnu8H+cRLMKtSyPRJtGYOd6KjbvItNho3J7Ie72bhLbu6kurMXVIZOE3CzK/CZaZgdqghYe08JyZWKGU8mU+8IR3JJaPwXVPpyaQkGll4JKL4k2leIqL54aP3aXgafGhzPZgTPZQcDnx5kajyM1kaDfgz0pAdPnwQoGUF1JmAF/OHrrSg5Hi+0JhIx4ACx7AqbuAMBnxsSjzXA8WlE1avxBFC28XhcwUXUbdQGT2vootMdvUu0NRmPTqm6g2sKxaUXV0HSVYMBE01SC/vp4dDQ2HY5FW2YoHFHWVaxQCFVTUFSFUCiEVh95toL+aPTZCvgbxKYj65qqRGewjX3jaxCPrm8L++KtqrpvaFtT9v21pyn72miqgtVov5BpRuO5mqKgKpHziNkv0rZ+e0RktDk2Jq0oMfHnBjHng//lGnnuxvsefL/9z6nB44d+qANGlQ90Okey8ntrVpFv7Zi0pLQbmjJlCv/4xz945ZVXWL9+Pbfffju7du3ixhtvBGDq1Klcfvnl0fbTp0/nvffeY/Pmzaxdu5apU6cye/Zsbrnllmib2267jc8//5zHH3+cDRs28Pjjj/PFF18wefLkn+x1yGUjIYQQohXoMX9QNEdz5ja68MIL2bt3Lw8++CAFBQX07duXOXPm0LFjRwAKCgoa1Hzx+/3ccccd5Ofn43Q6Oeqoo/j444857bTTom2GDx/OzJkzuffee7nvvvvo2rUrs2bNYsiQIc1+bQcjnRchhBCiFbR0Vunm7jtp0iQmTZrU5GMzZsxo8P2dd97JnXfeedBjTpgwgQkTJjTrfJqjzVw2EkIIIcSvg4y8CCGEEK2gtUZefg2k8yKEEEK0Ak1pYeelDd+NLJeNhBBCCPGLIiMvQgghRCs4UkXq2qI2M/Ly/IALOL1nGsXrvmPrnX/nmQef5eu+wxlyyUT2eANcN286T9w3hxP/sYnt335A+9feY+w1l3Hu/XOoLc7j79fN4KbbL+G8vXO5/OEzee2ud5nf+RwefWYul/52ODVFOzjqlDO47aX/MuOSYyl+dDJpPQbz7tsbuHVif0537uGUo9JZds8zfLalnHmBdjg1lenvrCFv6Vf0ueN6ALKPHsnjn2zgopO7s+37JXjKC/F//CLx6bl0GnAM3xfVcu2J3agMWOQ4dAJfz2RglyS6nzOQVZvKiDvxPLZaSWgKvLO6gE5xBr17pVK8dROdxvXFNepUQpZJZWoP7K4UEjI78fm6QtJzUzm2RxoVu3cxoksqdXv3EPTWEF+xA0XVsLtS2LtiPXGp7ShZk0/5tgpSs1zsqgtQ6g/SN8uNx7QASNMDGKqCXraLwLY1pBka1Vt2ULWjgIScBKp2V+POdeHqkEGJL4irQyZ6TmdqTQs9syN+K4QZAo8erreiKbC3LnzMghofhdVe4jWVggovBRUeEm0a1dU+vLV+nMkOfJ4gjmQHjmQHgdpK7MmuaH0XR2oiVjCAGfSjJqaG66IE/eBwhdftCYTsCQBYRhzeYPg1eQL7arv4gqHwuhau7aLpRrTOi6Jq1AZMarzhmi413iCegImqG3jqa7+E1000XUfTVMzgvtouwYCJpitYQQvLDDV4XNXC2zVdjW436uu8hCwTu64SMsO1XQxdi9Z5MbR9j0faGroarulimg1qwhjavpovNk0hZFloioKtvo2q7qvXotYPeVv16xGR44Z/dvW1YhQlWsdFjSmJHrvfgeqBKAr1z9dwe1P1XRrUZTnIe8LB/NjnwpGo79LSfQ6l9HpzP9t+LR+JP/erKq0xq/SvRZvpvAghhBDi10EuGwkhhBCtQNJGzSedFyGEEKIVaGrLOiBaG752Ip0XIYQQohXIyEvzteF+mxBCCCF+iWTkRQghhGgFMvLSfG1m5CXNrtF1/le8/PwdXHLTk3QdeTpzdlQw/zwXU1+9lqvWpjEgycGSWa/T/zcXc9JD83j3zDQKVnzB2GsuY2utn4d7VjH74v+j9ML72VTj4+anv6Vkw2KS//giXUadySvXD2HzvA9x/vth3n/2Wy66ZCR5ngCTeuis+8O9DHv4SuYs3I3fCnH/7NWc3C2Zrd99jen3kN99PBlHjeCUMd3Y8O1KrhvUjuqCrTgS01n98pe0P/Y4LhvbjUJvkLN6ppJu1zgux8WmmV/S87z+pJ55IVtr/eyO68x764rIddr4alk+/Tol0mlML2oKd5A65hR8HQejOxJYXlhLQmYn0ju3Z93GUvr2TOfEHunUFO3g2Mx4ArWVAJgbl2DEJxKXmkPxql24s3LYu2EvO2r9DOycQqnfpCZo0TM1DjMUjjXre3eQoKsEtq+ldts2shw6lVvzKd9WTlJHN1W7q3F1SMfdOZsyv4XRvgt6dic8ZgjTlYHfCgFQ4Q3HbQ1VoaDah1NTKarxsbssHI8uqPRQVe0j3qnjqfHjrQ0Ql+rE7wngTHbgSE0k4K3BmerGkZqI6feiJ6UQ9HuwAn7UhKRoRDhkD8eyQw4XlhFe9wUtPPWxaK8ZikalayKRZ1Wj2h+OR6u6jWpfTDzaH45Q1/lNPP5wVLqu/qum6/j9JrpNQ9VVggELTVPD8ehgeN00rQYRak1T0WLW9frIs6Yq0Yh0JAYdiUJH1u26ihUbj67fLzY2HbLC/9aRGHQkIh3ZFqknodbHpiH8xhmJN2v176Ehs2GkOXI8TSWmbcx+KtHnjhWJQStKo/iz0vDx2G0HEhvBjm0b++anNIhs73+MQ4ncNhVdPtBnS0s+cg4lIv1jz33Q4zdvtyaev/U+WH/uEekI9RDj0AdapM6LEEIIIcQvhFw2EkIIIVqBFlOwsbn7t1XSeRFCCCFagRpzCbW5+7dVctlICCGEEL8oMvIihBBCtAKNfTe7N3f/tko6L0IIIUQrUFuYGJK0URtw3rr5HHfNiwx+5Xck5vZmxR+HcPcDp/C3AZfxVNp5/Ofpf3Dpf/9F1xPOYf4dw9k4dzbzTrqIwRdexjvnZHPNeb34bOwNLCit48KnvuXSkR3Ytegj2g0+jfP+uYxnJw2j2/evYHel8OEf3mVNlY9Hx3bkxPQ4dj5wBx+8v5mC4y6jzG8yPjOBdV/NZ9i9Z+OtLCG12wAe+mILx5/Ui9+N7kz5jjUk/fAhtvhEco4ZzqIlBZw7pisX9s0k0abiXPkhg5Od9PxNX1bP30XmOedRnN4PvxVizuZSPvrvbvq3c5G/cRedx/ck8+RxBL01mL1GsbKoloSsTsxZV0Rqx0507ZZK8Y5CxvTKYFCOC39tJRlWBQC2+EQqly/DmZqDK6sDpRv3kpbjZkeFjyJfkAEdkqgMmJghaOeyoSmQoKsEd6wl2abh2baZis15JKXFUb69jKrd1SR2zqCk0ktS13bYcztTHjDRczpjujLxWyGCrozoz6y0LoihKjg1lYIaH/Gays7SOgorPSTaVPZWeqmr8eNIduCtDeCtC6/7a6txpLpwpLqjM0nbkpOxgn5UdypWwB+epdiVEo3pWg5X+KsRjy88kTSeYAifaTWcSVrVqPaZqKoWnh06YKLqtuhM0aotHJWujswq7QtGZ5OOzCStaiqWGY5BRyLSuqESDJiY9dvNYIiQFZ5VOmSF0HQluq43NTt0/UzSVtDfYCZpyzL3j0eb+/aDfbUiQpbZ4K/ASMzZpu2bSVpT9rUPzw4d07bRTNLhYxPTtuEM040j0rGX76OR6EbbmopIH2gm6cg5Nz724bzpNXVLwaHs39yI9ME+iw41Jt0cR/LIEpMWPzUZeRFCCCFagaSNmk86L0IIIUQrkLRR80nnRQghhGgFqtKyG3bb8C0vbeeeFyGEEEL8OsjIixBCCNEKJG3UfNJ5EUIIIVqB3PPSfHLZSAghhBC/KG2m89L/tvdQVI3/e2Yxq1+4gA96nsiXp91DkS/Iw/c+R9YxJ3Lqpz4WPDCWZeNPoc+pE5i9YS9f/XYw3512MT1ee5f3d1ZyQb8M1n/2NsfNfJmMPiN4/Jbh/PftDxmZ/zlzb3qZweeexnd7PQxOdlD86GTG/vF0Pnh1JXmeALe/t5ZRaXEM+8Mp1JbkEfrN70nq1JeBY47li8/Xc+/4nuTuXIBmONn419fIPnokp53UlU01fq4e1J60LV8zONnJztf/Te9zetH+/PNYVemjqsvxfLaljCyHzqxFO9m1fjddx3ejMm89OaecBEePRdUN1pSZzFlfTGqnbixaW0TnHqmc2jeL6oItDG2fSHvdQ8gyUbYvR3ck4EzOpHjFFtzZnUhr52ZnSR19OidT5AtSGbA4KiMBMxS+4cwo206CrpJs0/BuXU+WQ6Ns/Q7KN5eQ1NFN5c5K9pZ7cXfKosRn4mifi619VzymhZWUg+nOAqDME67LYagK+dVenJqCQ1XYVVpHok2lsNJDcYWXRIeOp9qPp9pPXFoc3jo//tpqnGkuAnWVOFITcaYmYvo92JKSUN2pmAE/WmIqIcsM10BxuKJ1QEJGPAC+kIonGK7t4glaeALh+i7V/iCKqqHZDGr84Rouqm6jLmCG1+vru2i6QbU3WF//xcDjD9d80Q07Pr+JqqloukowYKHVr5tmeN00LcxgCN2mYQWt8HZdwQxa6DYNXVcxg0GM+jovVsCPXVcxdC1axyXy2jRVwapfj60JE1mP1nyxTGyqGv13sGkqIcuK1neBhvVcbJqKqoSPrSn76rtoMcPXkb8GQ5YZXddi/sLUYt51Yv9yVBtVGmlco6WpGi8HEltD5kA1XmJrpjQ1+t74OZp6szycuist+Rv5cJ6nNa8kSH2Xw6MpLV/aKrlsJIQQQrQCuWzUfG1m5EUIIYQQvw4y8iKEEEK0Ak1VGlxybc7+bZV0XoQQQohWIJeNmk8uGwkhhBDiF0VGXoQQQohW0NLEUFtOG7WZkZfakp0sffl6bjq/N4v6DmNJuYebpzzL3e/eSXKnvsx77DS+fnkGOy86k399l8f8e07kwmMzWX7mGcxcVsD4ZxdxTpdkRn/wEqndBvDb7+qYdttYfuNbStDn4asrn2BOYQ2vT+xPX7ed034/ho+e+w79qgfZVONnaIqThR8v5IQ7xhB/9TTc7Xvw52920u/EwTx8Rh+KVi+gZ9lyNj/3NzL7jWLRp9sYd1JXJg3viFNTaF+0lJ2v/Yu+Z3Znzbvr6XjJBLz9TqYmaPHpljJe+24Hg5Kd7FhbSMWONbQ/Yyy+6jKUgaeyodZGQlYnPt5QxNc/FNKheyoF20o57ehsju+YjKe8iA6OAOrWJeiOBGqWLiQuLYfEdt0pXFlMWo6bPl1S2OMNMrRLCmV+E78VooPbAMCpqVi71pFs02jn1Clbv5OMFCflW0qo2FlFUpdUyvZ6KPGZxHXqRHnAxNahB6HkdnjMEKY7i71eC4AybxBDVXBqCgXVPuI1lUSbxu7ycFS6oMxDXZUPZ7KDuho/3jo/cWlO/HW1BL01ONOTCXhqcKYmYiQnYfq9aImpaImpWEE/qjtlX1S6Ph4N4FfC/fhwPDoclfYGQ9QFTBRVo8ZvotkMVN2gLmCh6jZU3aDSE0C1GdGItKobeAImNd7w9jq/GY1IBwMmmq6i2zSC/sh6eLuqq5jBEFYwNjZtoWoqlmmhx8ScDV3FHl3XwrHpoB9DC2+zLDP6eDQqXR9njlwjN3QVTQlHqyNvgCHLCkef62PGaszjkeHp2Ni0quw7Xuyld03dF1XWYvYLP4fZ4PvYUW8leh5m9HiKcuCIdLQNsduU/SLWcOCIdFOaerjxG2VTxzjQ7QcH+3w52G0LhxOTPlxt+LPvZ0Gpv2zU3OWn/N34uZORFyGEEKIVyA27zddmRl6EEEIIAX/961/p3LkzDoeDgQMH8s033xyw7TvvvMO4ceNIT0/H7XYzbNgwPvvsswZtZsyYgVI/EhS7eL3en+w1SOdFCCGEaAUq4cuGzV6a8ZyzZs1i8uTJ3HPPPaxYsYKRI0dy6qmnsmvXribbL1iwgHHjxjFnzhyWLVvGiSeeyJlnnsmKFSsatHO73RQUFDRYHA5HM87w0MhlIyGEEKIVaIoSvS+sufsfrieffJJrrrmGa6+9FoDp06fz2Wef8cILL/Doo4/u13769OkNvn/kkUd4//33+fDDD+nfv390u6IoZGVlHfb5NJeMvAghhBC/YFVVVQ0Wn8/XZDu/38+yZcsYP358g+3jx49n4cKFh/RclmVRXV1NSkpKg+01NTV07NiR9u3bc8YZZ+w3MnOkSedFCCGEaAUtSRrFFrjLzc0lMTExujQ1ggJQWlqKaZpkZmY22J6ZmUlhYeEhnfNf/vIXamtrueCCC6LbevXqxYwZM/jggw946623cDgcjBgxgs2bNzfzX+bg5LKREEII0Qo0teEs683ZHyAvLw+32x3dbrfbf3S/xhHrUCh0SLHrt956i2nTpvH++++TkZER3T506FCGDh0a/X7EiBEMGDCAZ599lmeeeeZQXsphazMjL/P+/ls2jhhNxaP/4sv8au5/axLx6bncXjOEr56+iMobJtBh6Gn845OtTOiTzsbzTmfEl+/y6rydnNnezZJ/z2L853/j96t07plyOjNfeocr7Rv56tJp9D/7HN7fWUlvlx3tlXv5zZQTcN32Z1ZVepny4QYGJzsYf/sJVOxYQ9Kkh/jLonz6jRnOG++v44nf9KNvzRoAtkx/hoXvb+Kkk7qyqtLL5FGd6bx3JQOSHOx65WXW/nsNnS87nyXlXvwDz+aTLeWk2zVe+W4H29YU0fXkzpRtWY63sgT1uDNQdYONXicfri8itVMv5q7cQ/7WvZzZP4fKXesY3SmFznFWuJbH1v9Ss+w7nMmZFP53Ha7sbqTluNldWEOvLikMq6/vMiDbjd8KARBXvYcEXSXN0PBtXk2WQycjxUnFliKSuyRRvq2CvSW1JPXIpdBrhuu75HanJmgRSmmP6Q5fHy3376vvsrvSi1NTiNdUdpTWkmjTSDFUiiq8JBs6dVU+6mr8ONOceGp8+OtqcaYmEKitJOAN13cx/R7saSloyemYAT9acgZqYmq4BorDFa0DEnK4or8ftfW1XTwBC08whKJq1PpNKn1BNJtBtS9cw0VRVWr8QRRVQ7UZ1HiDaHq4/ktNfZsab4A6vxmuCeMNRuu7BAMWuk1D08N1XHSbGq3vomkqVtDCNC00XcEMWlimhWFomMEgRn2dFyvgx66rGLoWreESqe9i6CpWbG0Xy4zWdwGixwjXblGwRWq0qAohK1xnJ7boVWw9F5sWPnak5kvkuJGkZuTae7hGS9NvgpE32nB9ivr1RpVGmqrREtG4xkvjJpF9GzucGi8/tm9zjtGSIOvhPE9rJmZbs0R9Gy5z0oDb7W6wHKjzkpaWhqZp+42yFBcX7zca09isWbO45ppr+Pe//83YsWN/tK2qqgwePPgnHXlpM50XIYQQ4udEVVp66ejwns8wDAYOHMjcuXMbbJ87dy7Dhw8/4H5vvfUWV155JW+++Sann376QZ8nFAqxcuVKsrOzD+8ED4NcNhJCCCFagdrCtFFzRr2mTJnCxIkTGTRoEMOGDeOll15i165d3HjjjQBMnTqV/Px8XnvtNSDccbn88st5+umnGTp0aHTUxul0kpiYCMADDzzA0KFD6d69O1VVVTzzzDOsXLmS559/vtmv7WBadeTlhRde4Oijj44OdQ0bNoxPPvkk+ngoFGLatGnk5OTgdDo54YQTWLt2bSuesRBCCHFkHKkbdg/HhRdeyPTp03nwwQc59thjWbBgAXPmzKFjx44AFBQUNKj58re//Y1gMMjNN99MdnZ2dLntttuibSoqKrj++uvp3bs348ePJz8/nwULFnDccce1/B/pAFp15KV9+/Y89thjdOvWDYBXX32Vs88+mxUrVnDUUUfxxBNP8OSTTzJjxgx69OjBQw89xLhx49i4cSMul+sgRxdCCCFEY5MmTWLSpElNPjZjxowG33/99dcHPd5TTz3FU089dQTO7NC16sjLmWeeyWmnnUaPHj3o0aMHDz/8MAkJCSxevJhQKMT06dO55557OPfcc+nbty+vvvoqdXV1vPnmm6152kIIIUSLRdJGLVnaqp/NSzdNk5kzZ1JbW8uwYcPYvn07hYWFDYrp2O12Ro8e/aPFdHw+334Fe4QQQoifm9a4bPRr0eqdl9WrV5OQkIDdbufGG2/k3XffpU+fPtGbgg63mM6jjz7aoFhPbm4uALtOP5M5m8s4+4bpPDhzEr8LjWPec5fzyqPP4b3lQl58ZyPfPTKe83qlMmr+u7zy2TZOfm0LZ2S7OHXeS7jb9+DudfH88/n/cGPcZryVpXx5/t28u7mMWdcfR2+XnQm/O4F3H/yE5DufZspHGxmc7GDO7O84dcqJpE5+DFd2V/78fRH/nL2GJ87tR/6yL+nvWcvmP/+FzH6j+PbtdSyv8HLnSV3RFIXuFavZ9Y+XGHhaN1a/sYLFZR4Cx51Lmd9kzpZyXlqwjcHJTrb+UMjeTUvodN7J4Zi0brDZl0B8ei4frCvi0+X55PZMY/fmvVTsWM2JnVLxlBfRNd5C27IYzXBSs2QBBYvW4G7fk4JlhWS0T6R3t1R21QU4vlsqg9ol4rdCdEo0AEjQVdi5mjRDI8uhs3ftdrJTnSR3SWLv5nJSuqWxt6SWQq9JfJculAdMKgMmpHfEb4UwE3MoC4R//Uo9wWhEelell3hNJdGmsbu8jhRDJdnQqanwEpfmpK7Gj7fWT0JmPP66WgK1lTjTkwl4awh6arCnpWD6vWjJ6WjJGVhBP2piKpYzMRyVtu+73OhXw68lEpFWVA1PMESt30RRNSp9wWhEusZvoqgqqm5Q6Qmg2Z1oukG1N/x4JCKt2Z3U+U3qvEF0m0YwYEYj0mbQQtNVVE0hGDBRdTUakdZtGqZpYQYtVE3FMq1oRDoSfbZH17VwLDrox9DUaEQ68ng0Km2Go8Oxx9AUhZBlYlOVaETapoZ/DiHLRNf2rUfeGG2a2iA2HYleq8q+iLRNU6JR5dgbENX659PUfTcXKsq+iHSkafj59v//rKLsF5GGhhHkyHPEHi+87z5NxY5jn6+pz4DGb44HO0aDtk1vPuh+P/ZcR0rb/bgTvyat3nnp2bMnK1euZPHixdx0001cccUVrFu3Lvr44RbTmTp1KpWVldElLy/vJzt3IYQQorkUpeVLW9XqUWnDMKI37A4aNIglS5bw9NNPc9dddwFQWFjYICt+sGI6drv9oNUFhRBCiNamouxXqPFw92+rWn3kpbFQKITP56Nz585kZWU1KKbj9/uZP3/+jxbTEUIIIcSvW6uOvPzhD3/g1FNPJTc3l+rqambOnMnXX3/Np59+iqIoTJ48mUceeYTu3bvTvXt3HnnkEeLi4rjkkkta87SFEEKIFmvppR+5bNRKioqKmDhxIgUFBSQmJnL00Ufz6aefMm7cOADuvPNOPB4PkyZNory8nCFDhvD5559LjRchhBC/eOHpAVq2f1vVqp2Xl19++UcfVxSFadOmMW3atP/NCQkhhBDiZ+9nd8/LT+WLLWU88t4dxKW247eBMbzy6HN4bphA5+PP4IX/rOeCfhlsn3AGoxd9wrhXt3B2x0QWvfEmp373KrevjudPd5/HS0+/ha+6nC/OvYtBEybw7uYy+rrtGK/cw/l3noT799NZXuFl0rvr+GDWfE77/Rj2bllO6u1P8PiiQo49ZRSv/Gc1u5d8zoC68EzSm574P759ex0nn9KH5RVeDFWhW+lyhqY42fHC86x+YwXdrruU7/bWUeY3+WhzGel2jb99vZUtK/PpcXo39m5agreyBG34b1B1g/j0XN5bV0h69758sjSfvI3FnDeoPRU7VlO3dw/d4oNYQT/alsVUL/6auNQc9ny7mvz/FpDZIYntu6vo2yONUT3SKPWbHNc+ic5J4ZugE6rzozNJezeupJ1TJzvVyd51e0jukhSNSEdmki71BzE69aIyYOIxQwST2mOGoCygUuoJzyS9s8IbjUjHziS9u7SOZEOPRqQjM0n7amuIy3ATqK3EX1tJXEYyQU9NNCIdnUk6KT0cj3YmRiPSTc0kHYlINzWTdCQiXeMPohlONLtzv5mkI9sPNJN0JCIdDJjoNhXd0KIzSUci0k3NJB2dKfogM0nbY6LQsTNJhxrNMN14JulIRFpTiLaNrAOHNJN0JCIdW28ish6JSEe2xc4kHTvc3XTMWdl/m3LgiPSPaZxOPNhfq4cyk3Rz/+I9khHpwz2HI/lHuswkfWRI2qj5Wj1tJIQQQrRFkjZqPum8CCGEEK2hpaMnbbfv0nYuGwkhhBDi10FGXoQQQohWIGmj5pPOixBCCNEKFFp25acN913kspEQQgghflma1XmJFJfLyclB13U0TWuwCCGEEOLHqYrS4qWtalbn5corr2T58uXcd999vP3227zzzjsNlp+j+z/6IxfsGcCyv13Ovx5/ll7jfsPf3t/EysfGM3FELsMXz+OfX2xn1HM/sPjNNxi38N+kdhvANYvgn0+/zlX+RQS8tQy7+Hze21bO+zcOYUCSg4v+dAZvPfgptlv/wpUzf2BUWhwfz/qSsm2rSJz8F5I69eW+r3bxyqyVPHP+MeQvm4uiaqz/02Pk9D+JeW9vYHmFl6kndcVQFYamONn27HMMntCH5W+uYkFpHTXHnkVlwCLLofPiV1sYmh7PlpV57N20hE4XnIm3sgRVN1jniSMhqxMZPfsxZ8luuh+VQd7GAip2rOakLinU7d0Trsmx8Vt0RwKV331J/rerSerQi/wle9hZUM3RPdLI8wQZ1T2Nwe0S8VshOicZxFfuItGmYu34gTRDo51Tp/SHrWSlx5HaLZmyLWWk9swguVdH8j1BErp1o9QfpCZoYaV1wmOGANjrC/88SuqC7Kzw4tQU8io90fouO/fWkmKopDht1FX5iEtzEp8Zj6fGR0JmPL7qKvzVZTjTk/HXVmL6Pdgz0jD93mh9FyvoR01Kx3ImRuu8hJyJAHgVAwBF1aiLqfNS5QuiqBqVviDVviCqblDlC0bru1R6Aqg2A003qPaGH9cMJzXe8HbdsFPnDaLbNIIBk2DACq/7zWh9l2DARNXDtV2sYPjxSH0XVVOxTAszGIzWZYnUdwnXatHCNV+CfgxNDa9bZn39l5g6L+a+2i5AtL5LyDKxqQo2TSVkWdhUNVrTRa+vGQPh2i5AtL4LhN9gtUh9GIVofRibtu/NU2s8+3v98SKPK8r+tVvC9WH27RMb+2xc3wX2r/HSZNuYNrE1U1Sl4dfG+x1IU3VXDnSfwcEOd6TuT2jOcY7UR5zUdzmyFFpY56W1X0AratY9L99++y3ffPMNxx577BE+HSGEEEKIH9eszktubi6hUOhIn4sQQgjRZqi07MbTtnzTarNe+/Tp07n77rvZsWPHET4dIYQQom1QFKXFS1vVrJGXCy+8kLq6Orp27UpcXBw2m63B42VlZUfk5IQQQgghGmtW52X69OlH+DSEEEKItkWK1DVfszovV1xxxZE+DyGEEKJNaenM0G34qlHz7/cxTZPZs2fz0EMP8fDDD/Puu+9imgefnr61nPF9Bp+98HfWjjiBgedfytLf9eXGc3vydd/h9JjzGUMenM/lozqwfPabZPcfy+nvlfLKtHP497MzUFSNt899kDOuvZiPrx3AqLQ4yu+9moufvojaSx9gfbWPi19bzrx/f8aZf7mAyl3rSesxmMkfbmDsb0by5szFFKz4gu7bPkWzO+k4dDyff7CZi8/uw6pKLwm6SruNn3BiejyDLz2Wxf9ZS+cbr+e7vXXUBC1mrS0mx6EzNMfF1uXb6T2hL6WbluCrLkMZPgHNcOJu34M3l+eT1bMvffplsmvtLiYMbE/FjjV4yovorNeE47LxiVR8O4/4jFx2L1hD/pICsjunsKWglh11AU7onkaJL8jgdol0TbKjKeAs24a1dQVphk7d6mV0iLORnZlAyZp8UrqlkNonh8KSOlJ6dSK+Ry/KAya2Ln2pDFh4zBDBpHbRn0NJXQBDVdhaVseOijrcusbmohq2ldSQbtfYs7eOFKeNuDQntVU+EnISiM+Iw1ddRXxWEoG6SgKeGuKzUwl6azH9XrTUbII+TzginZwZjUdb9fFoy5GIt76fHhuP9gRC0fVKbxDNZlDpDVDlC6LqNqr9wWhEurIugFYfj670BNAMJ6otHJvWDTuqFo5C64ZGMGAR9Jvohlofmw5HpM1gKByP1lRM00LTlXBs2rQwDA0zGIzGnK2An5Bl4jR0rKAfp6HhtGnRx+0x8ehIRDoSmQai65GINIRj0GokNq0p0Yi0FvMGqCoKVkzMOWSaaKqy7xiqiqZGYs5KNCIdidCGLBMt5l0l8uaqouxbj/lr80BvvrHR5sYR6chrPNQ37sZ/nTa1X1NvhI3vJ2juX7kH2+9w7ls43HM4kp9tEpM+8tQjsLRVzRp52bJlC6eddhr5+fn07NmTUCjEpk2byM3N5eOPP6Zr165H+jyFEEIIIYBmdtxuvfVWunbtSl5eHsuXL2fFihXs2rWLzp07c+uttx7pcxRCCCF+dSRt1HzNGnmZP38+ixcvJiUlJbotNTWVxx57jBEjRhyxkxNCCCF+reSG3eZr1siL3W6nurp6v+01NTUYhtHikxJCCCGEOJBmdV7OOOMMrr/+er7//ntCoRChUIjFixdz4403ctZZZx3pcxRCCCF+lZQWLG1ZszovzzzzDF27dmXYsGE4HA4cDgcjRoygW7duPP3000f6HIUQQohfnchlo5YsbVWz7nlJSkri/fffZ/PmzWzYsIFQKESfPn3o1q3bkT4/IYQQQogGWhQT7969O2eeeSZnnXXWz77jsvzd/3DazdfzwYZSvpvgYGbvkzGe/w9zdlQw9M5PWP/Z2/T66FO6n/gb5jx0KvP/+S+O++pJ4tJyuOH2S1lQWsfrp2Ww8coJnPuvycz42xK2j72di/72Pef1SuW/b39IbUkeJaf9jqxjTuT8i47ng1nzmX52H4rXfYfdlcLSPzxHt+PHcdMF/dhU4+eu0Z1It2ucmJvI2v/7BwNvHEGnWyazpNxLXrth+K0QXeMNZny+meO7p9D3skHs3bKcDpddSqC2Et2RwNf5PpI69Candy++/G8egwbkcOGgXCp2rmFM52Q85YXheh8rv8DuSsGV2YldX60htVMPdi/KZ3NRLcP7ZJDnCVDmNxncLhEzBF3cGvaiDSTaNMwN/6VqxRI6x9soWbGJ7PYu0nqlULa5nPS+7Uk9qjP5niBxPftgdDmKyoCFldoRvxWevLOwJhCuF6OF67sk6Crby+vYXFhDiqGxraSGwr11JMfbqKnwEp8Zjys7gdoqLwkZ8cRnp+CrKSM+OxV/bSVBby1GegZBv4egz4OWnI4V9IcXZ2K4zktcMpYjXOfFaynU+MP1XWpj6rxU+sI1XDSbQaUviKqHv1Z4A+H1ugCVdQF0w0m1Nxiu7aIbVHsDaHYnumHH4w2i2zR0Q8PvM9E0laA/XNslUs8l6LfQbVp0W6T+i27T0HUVMxgM13YJ+rECfuKMcD0XK+iP1msxtHBtF8syiTO0fdsjdV4ss1Ftl8i6hU1TCVkWqqJg0/bVZYmt/2JZJlZMzZeQaUbb2lQlWl9FU/fV+9AUZd96fe2XyLEj1PrBbaX+r8TGNVrUmMHvpoITjWu8NNU29k0sNn3R1F+lhxLOaCrBcaC/cA92uCPxl3Fz/8I+Un+US32Xn46kjZrvkEdepkyZwp/+9Cfi4+OZMmXKj7Z98sknW3xiQgghxK+ZpI2a75A7LytWrCAQCETXhRBCCCFawyFfNpo3bx5JSUnR9R9bhBBCCPHjWpI0akni6K9//SudO3fG4XAwcOBAvvnmmx9tP3/+fAYOHIjD4aBLly68+OKL+7WZPXs2ffr0wW6306dPH959991mnt2hadY9L1dffXWTdV5qa2u5+uqrW3xSQgghxK+dWn/fWEuWwzVr1iwmT57MPffcw4oVKxg5ciSnnnoqu3btarL99u3bOe200xg5ciQrVqzgD3/4A7feeiuzZ8+Otlm0aBEXXnghEydOZNWqVUycOJELLriA77//vtn/NgfTrM7Lq6++isfj2W+7x+Phtddea/FJCSGEEL92kVmlW7IcrieffJJrrrmGa6+9lt69ezN9+nRyc3N54YUXmmz/4osv0qFDB6ZPn07v3r259tprufrqq/nzn/8cbTN9+nTGjRvH1KlT6dWrF1OnTmXMmDFMnz69mf8yB3dYnZeqqioqKysJhUJUV1dTVVUVXcrLy5kzZw4ZGRk/1bkKIYQQopHYz+Kqqip8Pl+T7fx+P8uWLWP8+PENto8fP56FCxc2uc+iRYv2a3/yySezdOnS6H2wB2pzoGMeCYfVeUlKSiIlJQVFUejRowfJycnRJS0tjauvvpqbb775pzrXFvnDQ5N5K+O/PPzPK3ii/5Wsr/Zz0s3/5O4HTiF/2VwGX3gZw++dyzcPjMHx+I2k9xrK01Pe5rH7LubR7mVcOrQdi8++lBnvbODzDmfht0JcOv1bVr7/Die++TABTw2dhp/O5S8vZfI1w3n85C6UbVuF453HScjsRJ+x4/jk+3ymXnwMN/ZLItdpQ3n3/xjTN4Mhd5zMvC93kHndFNbG9QTg2e920ttlZ/ixmWxbtpJ+V40gZ+I1BL01lHc/EbsrhdRuA3hl0Q469OvJ6MG55K/byMUD2zOmcxK+6jKya7ejqBrO5CyK5s7D3a4H6V27kb+0gPbdU9lY4SXPE2BMj3TK/CZmCDo4AhiqgrFnNf4135Hj0KlYvpySFZvJ6JRI8eoi0vukkda3A7vKPKT07YyjR1/KAyZ6574EUzvht0LUOtMA0BTYXeXHUBUSdJXNpbUk2zQ2F9WwraSGdLtG6V4PVWUeErITqKnw4spOICHHhb+6jIR2aSS0SyPoqSEuK5Wgt5ag34OWmoUVCMejlcSMaATXiksGwHS4qQ2Go9o1fou6+oh05KtqMyjzBNF0A81wUOUNoBkOqn1BKuvCUejKugAVnvrYtMePZnei2Z3UeIPohi0af9Zt2r71+hh0MFAfj/ZbmKaFblOxgha6oaLbNMyghd3QcBoaVrA+Hm1G4tHhbZGIdMgysTeKRDvr2zeISmvh/84hKxxzDlkWEI46R7ZFIs82VUFTFSzLbDD0bNNUQqZZ/7PbF6uuP3R4vdH2UKNjxP41qCiRxxtui41QRzRoQ+z28DnH/qWpcnhvXk1Fqw8UsY71U0WkDyXi2twkyZEMoEhM+qelhEItXgByc3NJTEyMLo8++miTz1daWoppmmRmZjbYnpmZSWFhYZP7FBYWNtk+GAxSWlr6o20OdMwj4bCK1M2bN49QKMRJJ53E7NmzG0zMaBgGHTt2JCcn54ifpBBCCPGrE7LCS0v2B/Ly8nC73dHNdrv9R3dr3HkOhUI/2qFuqn3j7Yd7zJY6rM7L6NGjgfANPB06dGjTBXKEEEKInwO3292g83IgaWlpaJq234hIcXHxfiMnEVlZWU2213Wd1NTUH21zoGMeCYc88vrDDz9g1Q9DV1ZWsnr1an744YcmFyGEEEL8OCVktXg5HIZhMHDgQObOndtg+9y5cxk+fHiT+wwbNmy/9p9//jmDBg3CZrP9aJsDHfNIOOSRl2OPPZbCwkIyMjI49thjURQlOnQUS1EUzPpr5kIIIYQ4gCN02ehwTJkyhYkTJzJo0CCGDRvGSy+9xK5du7jxxhsBmDp1Kvn5+dHk8I033shzzz3HlClTuO6661i0aBEvv/wyb731VvSYt912G6NGjeLxxx/n7LPP5v333+eLL77g22+/bf5rO4hD7rxs376d9PT06LoQQgghflkuvPBC9u7dy4MPPkhBQQF9+/Zlzpw5dOzYEYCCgoIGNV86d+7MnDlzuP3223n++efJycnhmWee4bzzzou2GT58ODNnzuTee+/lvvvuo2vXrsyaNYshQ4b8ZK/jkDsvkRfWeF0IIYQQzRAKhZeW7N8MkyZNYtKkSU0+NmPGjP22jR49muXLl//oMSdMmMCECROadT7N0ewidR9//HH0+zvvvJOkpCSGDx/Ozp07j9jJHUnnffEEfzj3Ke51nUeiTeOP799F3d49fHnaPVz6uxv4+qrObFvwPlvOP4Nnn13EOw+fDcClxR/x8Yk3MfT9N3hjcT6Zdp1bn5zP1Vcey6Yv38PmTODf9OWoU87isRuGsOrjj7m1m0Xp45NJ6zGYL6fOZvBZY3jysv6U+U0mpFVR8eL9nHxCBxY99D7HTT2P+EvuYFONnwV1KTw6dxODkx18/MUWRpzYkWNuGkfV7k0kX3A9O5KOIi41h3fWl5DWayidju7I8iX5nDWiI5cNbE/l7k2M7OAmuegHVN3A++37xKXmkNihNzu+2khWtw706JXG6kofZ/bPIc8ToDJg0T8rHgjP+qxtX0qaoeFdsYC9S1bSNdlB8YqtFK0uIaNfBsVbykg/pgspR/ek0BvE3uNYtA69qQlaBNO6UKmFbxorrA3WzyStsq28jkSbFo1IpxgqmwurKS2tIzHFQXW5h7oqH66cBDzVtbjbJ5LQLh1fTRlx2SnRiLQtI4egz4Pp86Cnt4vGia34fak3vy38Wmr8VnQm6ZqARZXPRNUNSuv84ZmkdYMqbwBVt6HqBuWe8AzTZTV+Kupnkq7wBKisC0ekK+oCaIYT3bDh8wWj8eiAz0Q3NHRbeDbpcGTaCq8b4fh0ZHs4Mq1FZ5A2dJU4Q8MK+HEaevT1OG3hWaXN+gi1Wd/2QDNJR+LUkUh0yLKwqfti02pk9mh130zSWsx65GvIbBhp/rGZpBtvbxhFVvY9d/32hjFn5aAx2MhzqIrSZMw5fEylwdfwfrGPN/zaeP+DOdyY9KHEow815HC4MekjHY+WiPT/SOSyUUuWNqpZnZdHHnkEp9MJhIvTPPfcczzxxBOkpaVx++23H9ETFEIIIYSIdVhR6Yi8vDy6desGwHvvvceECRO4/vrrGTFiBCeccMKRPD8hhBDiVylcaK75oydKSy45/cI1a+QlISGBvXv3AuE41NixYwFwOBxNznkkhBBCiEbkslGzNWvkZdy4cVx77bX079+fTZs2cfrppwOwdu1aOnXqdCTPTwghhPh1aoWo9K9Fs0Zenn/+eYYNG0ZJSQmzZ8+OVtlbtmwZF1988RE9QSGEEEKIWM0aeUlKSuK5557bb/sDDzzQ4hMSQggh2gQZeWm2ZnVeACoqKnj55ZdZv349iqLQu3dvrrnmGhITE4/k+QkhhBC/TiELLOm8NEezLhstXbqUrl278tRTT1FWVkZpaSlPPfUUXbt2PWghm9by1NPfcXrPNF586BmuW/c+15UO4MWnfsvNU57lhXYb+az/WYy86ipe+WwbvV12sl++k1seP5uXLnmGOYU1XPRREaPS4rj20bPYs+wz2k1/g8QOvTn+orOZ+uwCXrtpGGcGVhH0edhwx2Q+fPobzr/oeD4rquWlC4/huPIljEqLY/tD9/HNX77i6Psm8dmWcrzjJ/HWFg9ZDp0HP1zHd19vZuj5R7Fn1bf0nnQhxhmTUFSNVVY2ry7LJ7vfccz4cgt9B7XjitFdKNm4jAn9sjjGHcD0e7Ct+ZzyT2eTkNWJ7R8tIrXbMbTrkcPmzWUM7JfFWcfkUOQLclKXVDxmCE2BlNrdJNpUMu06dcu/pXO8jaLvV1O4ZBvpfdIoXFnEnp2VpB/bne21ARL79sHeexDlARNyjyKQ1g0zBKVBGwU1AQxVYUuZhwRdxa2rbCisJtmmkW7X2FZYTVa8QXWZh+oyD+72bmqrvNRVVOBqn4yvsoT4dukktEsn6Kkhrl02emYHgo1ruySkEbLC01BYccnRn3NNIFzbpdpvUuO3UHWDCm+Qcm8AzWZQ6Q2iG040w0GlL4hmONHsTiojtV3qAlR6wjVdKuvCNV9sjjjqvI1qu9i0aB0X3abWr1vY7DpBv1lf00XFDFpYpoVhaAT9AZyGhrO+tkucoWHoWrReixX0R+u/mPWvM1LPJXa/BnVeNHVfvRZNJWRZ4RosCvU1X/bVf7FpKjZNxarfpioKIdNEU8NfgQb1YWyaEt0W2a4qClr9u0ZsDRY1ptKIUv/ckfXI45E2DequxNZlqf8a2Xe/tjH/nw9U2+VAmnqjO1DNlaaOp9D8WiqHM4Ht4dZ3OZJ+DrVd2lSNF9EizRp5uf322znrrLP4+9//jq6HDxEMBrn22muZPHkyCxYsOKInKYQQQvzaNGdyxcb7t1XN6rwsXbq0QccFQNd17rzzTgYNGnTETk4IIYT41ZJ7XpqtWZeN3G53g4mbIvLy8nC5XC0+KSGEEEKIA2lW5+XCCy/kmmuuYdasWeTl5bF7925mzpzJtddeK1FpIYQQ4lBEJmZsydJGNeuy0Z///GdUVeXyyy8nGAwCYLPZuOmmm3jssceO6AkKIYQQv0py2ajZDqvzUldXx+9//3vee+89AoEA55xzDrfccguJiYl069aNuLi4n+o8hRBCCCGAw7xsdP/99zNjxgxOP/10Lr74Yr766iueeeYZjj766J99x+W2m4bQfcE8+p0xgYHPbGXWX/7K6A/+RHx6Lk+ech+fFFbz+VkuLuiXwVWfPsb0R75k7elTyfMEuOS4HD59ZSYT3ptGwfl/JHfI6Zz50hJumXQ6/768PwUrvqDT/Of59roHOOqUs3j7nY2sqvTy+MldyHHopH/9IsunPsGJd47jszdXM6+klu1dx+ExLZ78difPvLeWk47OYMO3Kyle+x1dfnsLvuoyvMMv5tP8IKndBjB9/hbem7eNE0Z0ZMeK9dwwsgtn9Eyjbu8eugYLsBa/hyMxnaKPPmTrR8vI7H4UO+btomOvdMb0z2FTjZ+z+mUzqmMSfitEDxcYqkKKoRH8YT45Dhs9XQZ7vvuB3E5JFCzZSdHqEjIHdGJXUS276gIk9D2WIl8Qo9dgzKweeMwQda4c9tQG0RTYWellXUkNiTaV9cWReLTOmvxKshwa6YkOqvbW4cpJoKrcQ22VF3d7F57yUnw1ZbhyM/HXVuLqkIk9px0Bby16Vgf0jHaYfg9KakxUOiYeXWtpAOGItC8cla7xW5R5Aqg2g3JPILyuG5R7A6i6DVU3KKn2odmd6IaTvbV+NMNJWa2Pijo/mj0cm/bUR6T9viC6oWGz6/XrKjZ7TGzati82HQyY9evhbWYwGI45B8Px6Lj6daehR7c7beHItGWZxBlaNOZs6Coh02wYj9bD0eWQZWLX1WhEOhKJBtA1NboeiUerikJ9+rk+Nh2JQoe/hiwTTd0XVdbqc6uReHQkPq2p+yLPjePPIctsEPdtHKEOH29fJDg2Gasqyn4R6/Ax9jlYRLqp/Rq/yTUVXT5QRPlAyV1Vafj1QA4lJt3ceLSkin/5IhMzNn+Ry0aH5J133uHll1/moosuAuDSSy9lxIgRmKaJpmk/yQkKIYQQv0py2ajZDmvkJS8vj5EjR0a/P+6449B1nT179hzxExNCCCF+1WRW6WY7rM6LaZoYhtFgm67r0Zt2hRBCCCF+aod12SgUCnHllVdit9uj27xeLzfeeCPx8fHRbe+8886RO0MhhBDi10guGzXbYXVerrjiiv22XXbZZUfsZIQQQoi2QqYHaL7D6rz885///KnOQwghhBDikDSrwu4v0cdn3cOgq1/g+6sy2TD3XfqdcQGPPPAZ8567HDMEU347lFmDL2HEt5/yx9Ie5DptXPrH97n5thEM/fjf2BzxvKwdxwVPzOdvvxvF97Pe5p4eXkr+eD0ZfUbw3i3/4p0Vhbxyw1BKfEEGJDkofXwyZ5/Znfm/+xcffr2TxJseYk2VjwRd5a4P1jEqLY6ZH65n66JvGXTHOZRtW4UV9LMlbQDx6bm8uqqQJz/bSI8hvVi0cBd5K5dyw7COlO9Yw9iOCaTnL0EznHi+eIud73xKcpdj2PLxGjYuLeCYY7NYXu5hwnG5nH1UFpUBi2HtXbS39pKgq2gbvyXTrtMpzkbJt9/TMz2OrD5pFCwrIHtANns27GV7lY+0QX3J8wQp9Zto3QdQE7QIZHSnQksEYHdVgM17PTg1lXXFNayvn0F6bX4VWQ6ddk6dkuJaUtPjcbd3UVXmIbFjIrXllXjLC3F1yMRXU4a/uoyE3CwCdVXYsnLRM3MxfR70zA6EkrLCMeL4lOjP02/sm4ai2h+OR6u6QZXPRNUNSuv84ZmkdYPSugDlngCa4QhHou1ObM4E9tb462eYDs8grTsTwrNK1wXQDRs+XzAahQ74TAy7Ho5C+01sdj0chfab6IaGYa9fj8ajLez1MehIRNoKROLRenimaJuG06Zh1j9uxswqbQX8hMzwbNKRWaWN+vizoz7mHI5Hq9GItK7FzAhdn7+1YtZtqhKOVZvhOHNsFDoSUVYbRJGVaHw6sj02Hq3VzyodiUc3FXOOnS04Nh6tNHqOkGUeMOasRJ+76Zj0ocxE3NQxDti20dfGDiXafDgzSR+Olsxu3ZSfw0zSbZpltXxpo5pVYVcIIYQQLdTSEv9tuM5Lmxl5EUIIIcSvg4y8CCGEEK1B0kbN1qojL48++iiDBw/G5XKRkZHBOeecw8aNGxu0CYVCTJs2jZycHJxOJyeccAJr165tpTMWQgghjoyWTQ3QsqTSL12rdl7mz5/PzTffzOLFi5k7dy7BYJDx48dTW1sbbfPEE0/w5JNP8txzz7FkyRKysrIYN24c1dXVrXjmQgghhGgtrXrZ6NNPP23w/T//+U8yMjJYtmwZo0aNIhQKMX36dO655x7OPfdcAF599VUyMzN58803ueGGG1rjtIUQQoiWk8tGzfazumG3srISgJSUcCR2+/btFBYWMn78+Ggbu93O6NGjWbhwYZPH8Pl8VFVVNViEEEKIn51QqIVzG0naqNWFQiGmTJnC8ccfT9++fQEoLCwEIDMzs0HbzMzM6GONPfrooyQmJkaX3NxcAKbd/RQAT/e7gLsf+R3f39SZs7ql4LlhAnd8dB9lv3uBJeUeRk1fxnOPv8KN79xNyYbF+O98njP/vZPrb7uY+x9/h61fv8eIta9jcyaw8KJJ/Ov5Rdzz2zEsKK0jxdDovvx1zumZypl3juHDp7+h7+MP80leFWV+k8cX7qFrvMEpR6Xz/WdLOf7mkeQv+5K6vXswT/8ttvhEUrsN4ImvttJp8FBmzNnIpsXruHVsd4rWLKSmaAd91RKsoB9l4b8p/M9bJHXozcaZ37Dlky107teOVZvKWF/t5/wB7SnyBRnXNZWjU3UMVSGpdAPmyi/Jddqo+O4reroMunRMZPfCLWQPzKLdkC7s3FVF9rC+bKnxs8cbxN5vBGV+k5qghSe5E2YI9nhVtlX4cGoKa0tqWFtcTZqhsTq/ilV5FbRz6mzNryQryUFSBzeVe+tI6ugmuUsSnooy3B3S8FaW4Ksuw90pm0BtFQFvLXpOZ4I+D7acTqhp7bGCfsyEdKyEdADM+q8Alb59tV0q62u7qDaD4lofmi1c26W0zo9mOCjz+Cmt8aHZnZRU+bA5EsK1XTwBNMOJHq35YqemLoDPE8Bm1/F5ggR8QWwOjYAviG5TMex6tPaLzR6u6WKza+g2Dcu0MAwNMxjE9HtwOXSsgB/T58Fp6FhBP04jXNslUvslLqaOS8gyG9R2idR8CddtUbHrari2i6ZiU+u3awq6FmkTrpliWSY2TcWqr7sSqe1i05SYmi+RWjHh7RE2NaZWjLavDkykJodKzHps7ZYGNVr2r8eiKg3rk8TWlvkxjWu7HKy+S1NvaI1rrsSe0+E4WPtDqe3S3OeW2i6/UiETrBYsoYP/H/q1+tl0Xm655RZ++OEH3nrrrf0ea/ymEAqFDvhGMXXqVCorK6NLXl7eT3K+QgghhGgdP4uo9G9/+1s++OADFixYQPv27aPbs7KygPAITHZ2dnR7cXHxfqMxEXa7vcHEkUIIIcTPUciyCLWgSm5L9v2la9WRl1AoxC233MI777zDV199RefOnRs83rlzZ7Kyspg7d250m9/vZ/78+QwfPvx/fbpCCCHEkdOSS0aRpY1q1ZGXm2++mTfffJP3338fl8sVvY8lMTERp9OJoihMnjyZRx55hO7du9O9e3ceeeQR4uLiuOSSS1rz1IUQQgjRSlp15OWFF16gsrKSE044gezs7Ogya9asaJs777yTyZMnM2nSJAYNGkR+fj6ff/45LpfrR44shBBC/Mz9jEdeysvLmThxYjT8MnHiRCoqKg7YPhAIcNddd9GvXz/i4+PJycnh8ssvZ8+ePQ3anXDCCSiK0mC56KKLDvv8WnXkJXQIMS9FUZg2bRrTpk376U9ICCGE+B8JmeGEYUv2/6lccskl7N69O1qP7frrr2fixIl8+OGHTbavq6tj+fLl3HfffRxzzDGUl5czefJkzjrrLJYuXdqg7XXXXceDDz4Y/d7pdB72+f1s0kY/tWPOOo+lr9wEwK2bX+bVvmcz6oeF/O39TUwuO4azfvcGd9w3nhXvvoUtzs1T2vEMveRSznjgSxa8+iaP9a6mavcmsvuPZdY1L/Gbaycw8/t8Sv0mN6TkMyLVyQXn9+bL619k1PO3kTj5L6yq9DK7OosEXWVsRjz//M9qzji/F0MfuJS9W5aTfvN9hCwTV3ZXnv9+N+37j6bPyH589dVWrjytJzuWLKZs2ypO6+jEV12GZjipnfMqruyubHvjXTbOXkGHfj1Z8/0elpXWcdmITmyt9VPmNzmxUyJmCDqaxajr5pFp1/Es/IjCLxfQKyuevK9W06F/JrkjOrJrTQk5w3qRPmIQO+oCxA04niJfkMqASSCrN34r3MncUenHUBU2lNaxqrCaZJvGD/mVrNhZTpZDZ01eBYWFNaRnJVBRUkdiRzeJHROpLa8kqUsq7k7ZeKtKSOraDn91GYG6Kuy5nQl4ajB9HvTsTlhBP6HkHExXBgBWQho+IzzKVuFvIh6tGxTX+tHtTjQ9HJHWDAd76/zsrfWjOxMoqfJRXB+R3lvrj4lH+9CdCdjsBt76eLTfGyTgM+sj0UH8vmB4u8/EZtex2XWCAROjPh4dDIRj03EOnaDfR4JDx/R5sAL+aDzaCvqj8WinLRyPNiOxaUPDCtRHok2zYWzaMnFo+yLRkRizTVWw6/vWo/Hn2Hh0/baQaUZjuZqiRCPKNk2JRma1+q8hy0RTiUaYlZj9Im2U+rhyyDJRFBpEqCNig4BKzNfIc8dGrxtGrGP2axSRbnzsA+0Xq6ljHCiifKAE70H3O4zsb3Pj0UciXawqSqtFpGN/T8Qvw/r16/n000/5xz/+wbBhwxg2bBh///vf+eijj/abwiciMTGRuXPncsEFF9CzZ0+GDh3Ks88+y7Jly9i1a1eDtnFxcWRlZUWXxMTEwz7HNtN5EUIIIX5WLKvlC+xXmNXn87XotBYtWkRiYiJDhgyJbhs6dCiJiYkHLBDblMrKShRFISkpqcH2N954g7S0NI466ijuuOOOZk3387OISgshhBBtjmW17L6V+s5LpBhrxP3339+iWy0KCwvJyMjYb3tGRsYBC8Q25vV6ufvuu7nkkktwu93R7Zdeemk0SbxmzRqmTp3KqlWrGqSKD4V0XoQQQohfsLy8vAYdhAPVOps2bRoPPPDAjx5ryZIlQNOXRH+sQGysQCDARRddhGVZ/PWvf23w2HXXXRdd79u3L927d2fQoEEsX76cAQMGHPTYEdJ5EUIIIVpB5N62luwP4Ha7G3ReDuSWW245aLKnU6dO/PDDDxQVFe33WElJyQELxEYEAgEuuOACtm/fzldffXXQ8xowYAA2m43NmzdL50UIIYT42Qvtu2+l2fsfhrS0NNLS0g7abtiwYVRWVvLf//6X4447DoDvv/+eysrKHy0QG+m4bN68mXnz5pGamnrQ51q7di2BQKBBFf1DITfsCiGEEK0gMvLSkuWn0Lt3b0455RSuu+46Fi9ezOLFi7nuuus444wz6NmzZ7Rdr169ePfddwEIBoNMmDCBpUuX8sYbb2CaJoWFhRQWFuL3+wHYunUrDz74IEuXLmXHjh3MmTOH888/n/79+zNixIjDOkfpvAghhBCigTfeeIN+/foxfvx4xo8fz9FHH82//vWvBm02btxIZWUlALt37+aDDz5g9+7dHHvssQ0Kz0YSSoZh8OWXX3LyySfTs2dPbr31VsaPH88XX3yBpmmHdX5t5rLRJ6MqWXH8aG5b/W9u7XIO6XadY3//KbPO7cnQx19AsztZ89Cf6Fm7hNsv6Mftd75IyTuTSTjxbhI79OazsTcw+Obp3HVGHz765x94aXwGT8cZjBiYxYJL7uCcJy/EccqVPJN5ApndzuTvH25gUJKDB19bzsujOtDz/GHs+dtn9Jj9IIWJ3XEmP8ysXZBx1Aja9cjh1Q/Wc+4pPTilVwanvvFvrjz2dH5fkoeiapif/4O41BwSMjuz9rVXaT/sbtb+80221wb4zchOrPmTj5qgxTXd01hqhXBqCq7dy8hy6AQXf0DF+i0ck+Rg12dLKN24l9yh7dgydzuDbh5JUvcOzHplBb8ZejxaTjdKfP+H1WkAHrO+tkttCE0Bp6aysqCaRJvK8vxKdu6tY4hTZ/bOciorvFyW6mRvYTXe2gDJXZKoLqshpVsqztREPOsKSTymHc6MZPzzynF27ETAuwkr4Edv3w3Tv5CQZWK6s8JfXZmYtjgAakI2ar0miqpR6TOjdV5Kav2oNqO+tosfzXDUbw/Xbimp9lFRF0A3nBRX+/D4gw1qu+iGjepaP4ZdR7dp0Toufl+QoN/EZtcI+EzMoEWcy05NhRebXUPTVYKBcFtDV6O1Xey6iunzEGeE67lE6rVE1uMMDav+q6Gr0cc1VWnQFsCmqvV/Vf1/e/cdH1WV/3/8NfdOTZs0kkkgdAIoiALSdFEsCIqu4tpFdldx3RUVkXVF1hXLiuuqa+8NFX/YRb8iiiJYAKVFighILwmB9EkmU+69vz8mM8zAhECCTEI+z8djHjk5c++dmyPEw7n3/bk6FlXB0HXsqoJSt63NrETUawm2dV2Lqu1iUU3hAlah4+1f2yWy5kvoX3BqRDGSUO2WyNouasQ/dxTqqdcS1Y5d20UJH2Of+uqyNLa2S6zzidq2nmM0VNulvs852LEO15Gq7RJPUtvlEDS1Su5vWGE3PT2dN99886DbRBaa7dixY4OFZ/Py8liwYMEROb9WM3kRQgghmhW9ife8yFOlhRBCCCFaBll5EUIIIeKgOT/bqLmTyYsQQggRD0eowm5rJJeNhBBCCNGiyMqLEEIIEQ/NOG3U3LWalZf7R97F7A2lDHx1N5f0zWHyZ/ewdfEcrE+/S85JZ3HrlOu5+vbpfHf3GVy+eSYmRWHxORfSe9SlTJtyKbO2VjB3/CDOXPcWfziuDQVXX8M1/zqHgdOf4N3lhRSNuI37V9SSn2Tlry//yMdvL+D8289k47ef0f9//8R01V2YHUl85slhymfr6HrKUB55byUjzu3N5AuPZ8eyb7j5lA6c4ihB83mwff8Wdmcb0jv34eeXP6PtCQPpdnI3lqzYzfmndWJJmYctNT4u7e3CHdCxKiZyytbSxqbSMcFK6Wcf0MdpY9vsb9k8ZxV5p7Zj6zfb2LChlLyz+vFzpZeMU0/F3v9MdnsD0H0wNW3y0QzY4bfVxaNN/FTkJt2qkmlV+WFzKbl2C0s2l7J2axlt0xzs3llJ6W43GV3TqNhbg3vvXtK651BTspO0/DzSenbAV1VGUpdOWNvn4/e4sbTPJ+Bxo/k86Km54ZiulhwsO11tslNWF48u9WiU12ooZislNX5UmwPVYmV3tQ+z1YFqtbPb7UW1OjA7kigqr8ViT6KwopY9VbVYEp2UuL0UV3qx2BOocPuwOWxYbGa8ngBWhwWLXcXn8WNzmPF5AvgjYtN+b6AuNh3AajNjs5kJ+Pwk2c0k283ofh/JdjNJdgt6wBf+qgd8JNvMaAEfWsBHkt2MHvDhsKrBWLR/X9vQNezm4Fc94MduDsajQ7FoQ9cwqwo2VQnHoy2qEo5H281KvfHoUBQ61GdRgn/lLaop3B8rHh3spy7mvC/2qmA6IEIN0ZHgUDOygFZ9MedY8Wii3o/eL9YvrPpiyzGPR+wY8qFEmkOfcygx6dYakY4Vaxf1C/49b9qrtWo1kxchhBBCHBvkspEQQggRD3LZqNFk8iKEEELEg9HEyYshkxchhBBCHEVNvW9F7nkRQgghhGghZOVFCCGEiAcpUtdorWbyMrS9k5H/u5bUe96jw+dfcOXHP3PdHb0548ZXKXjlOlK/f50nKvby8/kjWPDDLv41Zw5vDX2TefNOw/b9W7TrnMYvV1/Ij/O2ct2S15jQ/Qpum/Exj64uIs9hYcwLP7Bt1QZ+uOV3/POLTwnUunG++Qymj2/na9sJvP/ZeroNPZu731pB0a/b+N/kUVw7/lE+njSVHP8evFWlpC9/nz0//EBax16sfeZtcvvcSHZ7J4vvfZJz/tKJUzqnM2+ilwn92vGIX0c1QQf3xnCUuWz22/Rx2snITWLT7AI6ndKOzV9tpqi8louuGcoXszdS5tdIHDKCXbXTUY7/HTWJbfDpBoVGCsV7a3GoJlYUVuG0qCSqCt9vLKGH3UK6VeGzLaWcl2pjx/YKPFU+0rulUb6nGm9VORnH5VK9cRsBj5v0szrgXbKX5PwuKCkZ+KoXYulwOqaUTDTfFxgZ7ffFo1Nc4f9GJbV6MB5dq+EJ6MGnRNf4qPJqmG0OdlR6MVsdKGYLxdVezPZEFIuVovJarIlOFLOV4iovZnsSxZW1eHwaFnsCpZVeAn4Nq8NCbY0fi82M2arg8/ix2lTMFpXqSi/J6Q6qK73oAR2bw4zfG8DQjXA8OsFuJsGqonk9JNvNWM0qms9Dkt2CVVWi4tFRT5XWtHA8OsluDj9J2m5WUU3UG482dC0cj7abo58erZiCsWibWUE17YtCh8Y1FIMO9Yf6Yj3lOVY8GvbFXdWI3Ov+8ejQO5Hx6NBnRB7jcOLRkfvtv2+sY0SqLx7dWBKPbpjEoptAbthtNLlsJIQQQogWpdWsvAghhBDNiTyYsfFk8iKEEELEg6437b6VVnzPi1w2EkIIIUSLIisvQgghRDzIDbuNJpMXIYQQIg5CqcKm7N9ayWUjIYQQQrQorWblpcuXs7niq+3c8M9hDP7LK5Ru+omK+/rxeskuNl0wkq+XFHLf3M+ZfurbtLGpTKj+ivmd09h01e9ZsmAb1y19nQn5l6EZBg9tzyDPYeHSpxexfc2v/DjpdO799GMCtW4yXnsGvrqdjK59ue3TdeQPG8E/Xl8WVdvFW1XKRdlnc3VVKdkFH7Bn4SLSO/dh9f/eoHhVMT1uuZTvpz7DBW92ZWDHNOb93cuEwR3IS1KYB3Su2Vfbpfz/ZtA3NVjbZf0HP9L11Hak5+cy74XFXPTQxcyZ8zaVAZ3k00ax3TMDn25Qk9sHn26ww5TG3rraLkt3VbK13EO2zcw3v5bQwxGs7fLFphJGpNpwZCawd2cVbY7LpKSwCn91BW16taVq41YCHjcZZ3XCu3wvAZ8He9eB+Kq/jajt8hVkdUJzOAEIpLYL/3cp8YJJUevquwSCtVqqfVTUBsK1Xdy+AGZ7IoVVteHaLjtLPeHaLoUVtZjtSag2B8WVtVgTkw+o7RKq3eLz+LE5zFG1XVRVwe+tjlnbRQ/4SE2woHk9pCZY6q3tYjUraAFfVG2XJLsZ3b+v5kus2i6hmiixarvouoZFVcK1XSyqErO2S6g2S6zaLqH+/Wu7qJHtGLVdYF/9l4PVdomsGxP7GHXbNrK2S331YSKPU+/xYnc3vN8h1HZp6Bj12b8uTlNIbZeWTx4P0HitZvIihBBCNCeGbmBoTZm8GEfwbFoWmbwIIYQQcWBoetMmL03Yt6WTe16EEEII0aLIyosQQggRB3LPS+PJ5EUIIYSIA7ls1Hhy2UgIIYQQLUqrWXk5fdzTVJcUUXJre96oVjjpoit44A838NyiBbze923yHBau2/YWP56YTe8/ncozlzzMzb/M4pa8kagmE3f8nEh+kpWTemdx0ROfsHrqSO56+330gA/HS0+hfv0v0jufwnXvruL4EaMY2MvFe299zav/vpw/XPcg/uoKRqefwpjqCuzONhQ9eT+Z+SdTMO1Vdq/eQ68pV7Fg8tPs9gb4x8gezJroZfKQDrgsPhaYTHSpXINv6Qp6Jtsoee9VBqU7SG2fwi8zF9P9jA6k5bfl8ye/5bInr8TaPp+1jyxgzBmj2VUbjEdX5QTj0aoJVhbX4FBN/LCzku118egv1+1hR2kNY5Os/N/6vYzMcJCYlUDxjkqyemeRmJ1IeWEhmb3bUb1+GwGPm8xzulC7dDdawIc9fzC+6gXoAR9qXg803xcYrm7o9mQA/Gl51PiD/0rY69HC8egSTzAerVis7KioxeJIYltFLW7vvnh0RY0fS6IzKh69o6wGSygqXe7BlpyCqipUVXnD8eiAXwvHowN+HXuChepKL87MBBTVRPmeYDxaVRV83gAJDssB8Wg94CPJbjloPDrJHmzrfl9UPDrJZg7HnxMsajgebVH2xaPDUekY8WgAu7nheHRkfyiuHIpHAwfEow1dQ637Z4uhazHj0UB4m/ri0WpETjhWzDnYbwofg6j+Q9vvSMSjI7dtKB59MBKPjttHH7Nk5aXxWs3kRQghhGhODE1Dl6dKN4pcNhJCCCFEiyIrL0IIIUQcGEYT00aGXDYSQgghxFEk97w0nlw2EkIIIUSLIisvQgghRBzIykvjycqLEEIIEQeGboSr7Dbu9ds9mLGsrIwxY8bgdDpxOp2MGTOG8vLyg+7zxz/+EZPJFPUaNGhQ1DZer5ebbrqJzMxMEhMTueCCC9ixY8dhn1+rmbzYU7M598brmfKn6cx98WYWjs0iz2HhtI/v44bR3Zn4zgQe/NOrDPn2C5YMv53d3gCXfV7J0MwErr24By88/v/480vXMuC916jYtpaKa+7HkZZN3sDz+MPLS+l30fmMv24oc976jBevG8DD53ajdNNPDGd9sP5Hdkc23nsXrj7DyD/tDOY/t5DfjezHl9/v4Os91dx//nGsd/uo8Oucle7BoZpou+07tM+ep4/Txs7XXmTdax/Tr5+LNTMW0/38fHpccjIrVhXT9bKzcV1wIWurfNhPvwTjpJFU+HVK0rvj0w2sionFO6pIMiu0sZn5fN0e8hwW5qzZzeerijguxcaKX/awbVMZuT0y2L2tnJx+Llwn5lC+YxvZfTvS5sRuVO/ZRlbfHnhKdlFbsRd7z774qisIeNwoHY5H83kwdI1ARkcAvMkuynEAUFwdYE9NANXqYHd18KvFkcSWcg8WRxIWeyLbKmox2xPZXu5he5kHW3I6m4qr2VHmwZrgZEdZDdbkdKzJ6RSW12JNSMSeaKe6yofNbsGeaMXj9mFPsFBb7aO22o89wUpttR+vx4890YLX48dqN2NzWMK1XVKTrGg+D6kJFgIeN5rXgzMh2Kf5PDgdFgI+D6kOS3Abn4ckuzlc0yXcDvhIsgW/huq46AE/hq5jr6vj4rCo2MxKuLaL3Rys6RL6CvtquxiahkXZV8MlVLvFopqwKErM/hDVFN0O1XYJ1W4xmfZtE7VtxG8EU8T+kbVdQpsr7PsFEnmMyJopSkQ9l8jaLqH9YtV22V999VUaqp/SUE2X5l7bRQnXyDHFrb5L5H83ceTpmt7k12/lyiuvpKCggDlz5jBnzhwKCgoYM2ZMg/uNGDGCwsLC8Gv27NlR70+YMIEPP/yQmTNn8t133+F2uxk1ahTaYca+5bKREEIIIcLWrl3LnDlzWLx4MQMHDgTgxRdfZPDgwaxbt47u3bvXu6/NZsPlcsV8r6Kigpdffpk33niDs846C4A333yTvLw8vvzyS84555xDPsdWs/IihBBCNCehe16a8gKorKyMenm93iad16JFi3A6neGJC8CgQYNwOp0sXLjwoPvOnz+frKws8vPzGTduHMXFxeH3li1bht/vZ/jw4eG+3NxcevXq1eBx9yeTFyGEECIOjtTkJS8vL3xvitPpZNq0aU06r6KiIrKysg7oz8rKoqioqN79Ro4cyYwZM5g3bx6PPPIIS5Ys4YwzzghPpoqKirBaraSlpUXtl52dfdDjxiKXjYQQQogWbPv27aSkpIS/t9lsMbebOnUq99xzz0GPtWTJEiD2PWGGYRz0XrHLLrss3O7Vqxf9+/enQ4cOfPrpp4wePbre/Ro6biwyeRFCCCHi4EhV2E1JSYmavNRn/PjxXH755QfdpmPHjqxcuZLdu3cf8N6ePXvIzs4+5PPLycmhQ4cObNiwAQCXy4XP56OsrCxq9aW4uJghQ4Yc8nFBJi9CCCFEXBztOi+ZmZlkZmY2uN3gwYOpqKjgxx9/ZMCAAQD88MMPVFRUHNYko6SkhO3bt5OTkwNAv379sFgszJ07l0svvRSAwsJCVq9ezUMPPXRYP0urueel4Jkr+H9ZP3J+fjrGXy7m2RMu5doVM3ngns9JfPY9/ms7izSLyin/Xcyfpszkln+dw+znX+fiuY/R8dUP8NdWM6/XWG6YX0mvcy/mkse+5ZLrLuLh8UNY+sHH/L8/9WdSD3Dv3kKPNe9T8tAEMrr2ZcXEqXQ+ZQR9RpzOnJlruPLiE/nXZX1YXOph2qiebPf40QwYoG2ijU2lZ7KN8hmPc0pGAhuffYGCZz6j/1mdWP3mUpZ+uZnjx5zGD+tL6XjlxWRedBXr3T7UUy/B0/MM3AGd7bZ2rCjRcKgm5m+tIN2qkms388nqIrokWumZbGXeykKOy0pk1dpidm4sJfekbHZvK6dkeyG5gzpRsWszrv5dyR5wHDUlu8jo15vkPv3wVpVhO35AMB5d64a848Ox4EBG5/BY7w1YMCkqhe4ARXWx6J1VXjaXeTDbHGwsq8HiSMJsT2RzWQ2WhBSsyelsLHYH49F7qtm0x42lLh69dW81tuRUCks92BMTsCdaqa704kiyYU+04HF7cSRb6yLSfuyJVmpr/PhC8ejauqi0w4Lf68OZZCUjyUrA4yYjyUpqQrAdGY9OrYtHawEfqQmWYAw6Ih7tTLCE49GJVjMJFhU94CfBomLoekRbQw/4cNS17WYFm1kNx6MTLCqGFoxVh+LRtrpYdShuHd5PVQHqjhHst5pNqErsyHPoGKH4s2oyobBv21B/ZAw41DR0LRyPjozLRsajQ3Uc9j9G1PEi+/f7GjpGLLEiyiZiR5Dr++xIRzMe3RSR8eijLTLKLvHo1q1nz56MGDGCcePGsXjxYhYvXsy4ceMYNWpUVNKoR48efPjhhwC43W4mTZrEokWL2LJlC/Pnz+f8888nMzOTiy66CACn08m1117LbbfdxldffcWKFSu4+uqr6d27dzh9dKhk5UUIIYSIg+ZcYXfGjBncfPPN4WTQBRdcwFNPPRW1zbp166ioqABAVVVWrVrF66+/Tnl5OTk5OQwbNoy3336b5OTk8D7/+9//MJvNXHrppXg8Hs4880xee+011Lp/nB0qmbwIIYQQcaDrOnoT7nlpyr4NSU9P58033zzoNoaxr8Kvw+Hg888/b/C4drudJ598kieffLJJ59dqLhsJIYQQ4tggKy9CCCFEHDTny0bNnUxehBBCiDgITl4O75k+++/fWsnkRQghhIiD0NOhm7J/a9VqJi+zepzK2ko//yhZzdTU48m1mznt7TLu6prOsFvfoWzraspm38sdN7+NanWw5ZH7SV42ndu35PL9rO8Y8efL+esDn1G5cz0r3plMz3Mm8uPEu2Hdt+i6hvrSnaz5cT0dhlzPgvH3sam4hotfvpFZV/2Pu6b15YTsZJ641cujZ3TGtncD35sV2q7+mC6JVto6zGx+/GFO65JOWudUlj+7gH5j+vLda0spqtW46YN/8PasB3AHdK45909sqXkdfdDF7KgJ4NMNVnmS2FZUTrpV5dMNe9lUXE2XRCvvL9/B71NsOO1m3l9dxMWdnCRmJ7JrYyntBuVSvKUIf00FbX/Xg8pv1xGorSb7khPxLNpJ6oBBqM4MvM98hK3XaHR7MprvC7S2x2PUPf24JjkXAJOisqs6gGK2YlJUtld6Ua0ONpV5cPsCWBOdbCipocoXwJqUxqaSaqzJaahmKxuK3NidbVDMVraWVGNNTmfr3mq8Pg17ipO9ZR4Cfh1Hko2aymAkWlUVPG4v9kQLZotK5d4a0rKTUM0mSne7yU5yUrytHC0QIDnRir+2Ft3vi4hH27CaFQK1btITbaiKKfzU6EDdk7GdCRY0b7AdGY+2KEowHm1RsahKOBIderKzw6KiB3wA+6LSEU+NtqkKqmLC0DQSLGo4Emuviz6H2iGhfosa/WTnyMizYiIciQ4dY/+nSkP0E6MjHkAdfup0cJuIdkQ8OjJqHDPGfAjx6Fhx5Xoj1vt93d+hxJgbE48+FKZ62o0VrydGg0SiRcvVaiYvQgghRHNi6E2850VWXoQQQghxVDXxhl1a8T0vEpUWQgghRIsS18nLN998w/nnn09ubi4mk4mPPvoo6n3DMJg6dSq5ubk4HA5OP/101qxZE5+TFUIIIY4gXdOb/Gqt4jp5qa6upk+fPgeUHA556KGHePTRR3nqqadYsmQJLpeLs88+m6qqqqN8pkIIIcSRFUobNeXVWsX1npeRI0cycuTImO8ZhsFjjz3GlClTGD16NADTp08nOzubt956i7/85S9H81SFEEII0Uw023teNm/eTFFRUfihUAA2m43TTjuNhQsX1ruf1+ulsrIy6iWEEEI0N6EKu015tVbNNm1UVFQEQHZ2dlR/dnY2W7durXe/adOmcc899xzQv6tW47zumfS7YQaL7hhGzoW/5/4b3mDoyoWUDrudlNwuTCw+jp7npHBCrywunfIRT0y9jOtveYLaij189/m/SHzyeSyJThwv3kFax16sue7PFBXspv9Nj/POvX9hV22Afy8ZyMfPlqIZ8Ni53bjNp3FJ6l4CP39FfpIVz8t3seuXrZzTI5OCf7/E2ed0IrWri/kv/chFD12MvUMX7jnvfs6+/gb+97+r8ekGgVOvpNR3HwAF3lQcqonZG0rZUVlLnsPC60u3s6OshotTbDy/cCvVlV4u6JbOsyt3c1s/F0lZiRSu307HM/NJyEqlbN4a2l/Wj8o31hPweUgfPISajxZi6BrWPn/AW/UUavcB6PZk9MA7+Fw9qdWDBSH2kIxJUTEpKtsqfahWB4rFyoYSDxZHEorZys973NiS09hQWk1FjR9rchq/FFVRVRvA7mzDL4VV2FPaoNocbNrjxu7MQFEVdu2pJsGZREV5LQGfRqLThru8Fk3TSUyxUV3pJTndgaoq7NlRQWqbRFRVoXhbOYnJVqxmhc3VbjJT2rK+ugpD18hKseOvrsDQNdok2wnUuslIDG4b8HlITbBgNStoXg/pSVY0rwcAZ4IFPeDD0DVSbGY0Xy3JVjOKyYQe8JNkC7V9JFgULKqCFvCRYFHR6+qk2FQFzR9R86WutkuoHovNrIRrrNjqnqga6o+suwJgUZRwTQ5LXV+otktkzZeQWDVdTBCuFaOYTJjq6sPEqssC++qjqEp0XZbQ9vXtF+sY9dWHidRQTZd694s4kYZqutRXV6Y+DdWbORxKVH2bo1tgpb46PCK+DM3A0IyGNzzI/q1Vs115Cdn/l5FhGAf9BTV58mQqKirCr+3bt//WpyiEEEKIo6jZrry4XC4guAKTk5MT7i8uLj5gNSaSzWbDZrP95ucnhBBCNIWuNy0xpLfiG3ab7cpLp06dcLlczJ07N9zn8/lYsGABQ4YMieOZCSGEEE1n6EaTX61VXFde3G43v/76a/j7zZs3U1BQQHp6Ou3bt2fChAk88MADdOvWjW7duvHAAw+QkJDAlVdeGcezFkIIIZpO10BXGj8B0Rv/QOoWL66Tl6VLlzJs2LDw9xMnTgRg7NixvPbaa9x+++14PB7+9re/UVZWxsCBA/niiy9ITk6O1ykLIYQQIs7iOnk5/fTTMYz6Z50mk4mpU6cyderUo3dSQgghxFFgaDqG0oQHM0pU+th387K3qMo6nurLHuSLW6fy7tIdDLh8DCf+fQ5/n/o3RvbIYtild7Hn64dJKFxFwuNLuOCXYv5qtePqM4zFv7+K48/9Jx06pTH9ljHcPmcirw97DI9m8PZ1JzN1kheHauJiZS2/2My47GZKHprAuW1T+PmOyZRsKOPcy47jm/tnU1SrMfbFP/PwNS8w+ZtHUVydWPLf87nikolUYqfUdw/rnb3RDIMks8L7a/fisptJMSs8t3ALQ1JsvPDtZirLa7m3Qwp/X7IdT5WPu4bmsWXNLvzVFXQZcRzFq36h87kn4WiTRuXz68kZ8zvUtCxq3p1D4uCrqH3q9WBs9rhT0HxfAeB1HQdAWWJbavw6JkVlS5VGtU/HbE/i11IPZkcSqtnKqqIqbMlpKGYra4qrsDkzUcxWVu+sxJHmYuX2Cty1fhxpLtYWVuKuDeBIy2TL7ioS09NQVYXSvTUkpNgxWxTc5bUkptTFowM6zswESgqr0AI6aVlJlBRV4eqYitWssH1dDanJLhKsKuuqyslJ7YTVrLDM4w5HorWAj6xkG/5aN4aukZFkDUbDk6xR8WirqqD5PKQ5QvFoHafNgh7wY+gaSTZz8KtVDUeNEywqFsWErmskWc2oiqkuCq1gaMG13ASLGo48h+LPdrMSPkZk22o27YtHm/ZFoS1KsN8cTFIH49F1MefQtqHIb3Q8OuJ4dcdQFVP4JjfVFBGFjopYHxi3jgz3qfvFoyOj0CGmqEhw9FeIjh1HtmPFmPePM8f6vPo0FLGOOm6MdlMSxaEo9NGOREPsKLtongzNwGjCZSOJSgshhBBCtBCtZuVFCCGEaE50zWjiDbutd+VFJi9CCCFEHMg9L40nl42EEEII0aLIyosQQggRB7phoDeh0Jx+kLTusU4mL0IIIUQ8aAaGqQkTkFZ8z4tcNhJCCCFEi9JqVl4GPbmZsp3fMOv5CYy8+l4CtW48H4wn4Q9v8Y/Tf6XoseVkdD2Tn4YPp3BDKWff9xJPXzuWf3zyKQPyUpnR7S7+b/ZQ2lDFP24I8HCbXdxnUclPMqM/OYlROcmkdU7l+2vv4g+X9CQ1vx2zHv6asc+P5eE/vkxlQOc/7z/Hk6/8Hs2A2hHj2VX7DJs6nE5RlQ+HqvDOrzVsK9tLl0Qrjy7YxMBUO+lWlYfnbuBfeSkkZSXywqJtjB/anvuW78BXVUqPi09k56o1BDxuuo49hbIXfyLg9ZA94Vzcc+eRNvxycKRQ+9DjqH3/im5PQQ98jLfDyRj6qwAUmjMxKSomRWV9aS1mexI/76mhyqdhS06noKgKtzeA3ZnJsl0VONKyUcxWlm4rx5HmQrU6WLG1jISMtsGaLzsrSMjIZv3OCgI+neT0VIqK3GiaTnKag4q9NSSl2lHVYG0XZ2YCimqieFsFuV3S2b5+L1pAp33XdHasL8LQNbJS27Khooyc1PZYzSoF1RXkpDqwqgqBWjdZyTasZgV/rZuslLraLppGmxQbmteDoWu0SQ620xKsWFQTmq+WVLslWK8l4CfJZt5X28Wqogd84TouWsAXruei+X0kWdVgLRUtWPNFVQjXfwnVV4nVtlsUlLoKIhZFwWSKrucCYFbZ11b21WKJrOcSKuFhUfbVhDErkbVi9v3Z31fb5eD1XCC6NogS8bW+ei6xaqnEqunSUD2X/TVUPyZy30M5XtSxY5zT4YpVx+Vo13SJ/Dip6dIy6ZqObmrCgxlb8Q27rWbyIoQQQjQnRhMvG7XmInUyeRFCCCHiQCYvjSf3vAghhBCiRZGVFyGEECIO5J6XxpPJixBCCBEHhmFgNKHOi9GK67zIZSMhhBBCtCitZuVlx/JvSMzuROrkMbTtez3Z7VN5ue+VjHvpHaZddREVfp0vdj7HEzn3oZrgw3NTmDI+wH3mZdTMW0lRZgK1U6+lYF0xV4/sypcX3MI1NwwgLb89r97+AX97dxKWjj2Z1OsaHvp4BgFnDj/d1YPSs29iV+3zWBUTn1Zn47SoJKoKD87fTK8UG/+a/Qu7yzz83ZXE1E9+xlPl4+XBbXlu3kZuHtmFhCwnG5es4oQ/DSYhK43CGT/Q4+aRlDy6hIDXQ84dl1D1+UfBGO6wSdQ+/B8A9D4j0Hyf4s7rT41fx6SobFcy8FQbqFYHK4trMNuTUC1WluysxO5sg2K28N22Mhxp2SzaVkZFjZ+EjFy++7UEtzdAYpv2/LCxhMQ27TFbbfy0tYykrLaYrSqbdlSSkpmG2aqwt7AKZ0YC5Xuq0QIGKZkJVO6tQdN0sts72bWpjPbdMzGbFXZvK6VTfgZWs8KWlVvJSQ9GovWAjw6Z3VhRVYqha7RNS8BXU0G7tASsZqWu7Qi2qytwpdqxmhUCHjfZKXYCHjcAGQlWNF8thq6R5rCg+WpJc1hQTaAHfKQ5LCgmE1rAh9MWjEQbmkayzYzm9wHgtJnr+lQUUzCOnGw172vbVODAqLTdvO/fBqEYs0UxhePR1og8szki42uJjDGbovtCkehQOzISXX8Uui5uvV8kOjIKHesYoWhy5LGUqM+LOB6x27HizJHHPlgU+mDHaGwk+nATxfGMRIc+RiLRxy5dM9CRBzM2hqy8CCGEEHFgaEbw4YyNfv12k5eysjLGjBmD0+nE6XQyZswYysvLD7qPyWSK+frvf/8b3ub0008/4P3LL7/8sM+v1ay8CCGEEOLQXHnllezYsYM5c+YAcP311zNmzBg++eSTevcpLCyM+v6zzz7j2muv5eKLL47qHzduHPfee2/4e4fDcdjnJ5MXIYQQIg4MzcBowmWj32rlZe3atcyZM4fFixczcOBAAF588UUGDx7MunXr6N69e8z9XC5X1PezZs1i2LBhdO7cOao/ISHhgG0Pl1w2EkIIIeJA14wmv34LixYtwul0hicuAIMGDcLpdLJw4cJDOsbu3bv59NNPufbaaw94b8aMGWRmZnL88cczadIkqqqqDvscZeVFCCGEaMEqKyujvrfZbNhstkYfr6ioiKysrAP6s7KyKCoqOqRjTJ8+neTkZEaPHh3Vf9VVV9GpUydcLherV69m8uTJ/PTTT8ydO/ewzlFWXoQQQog4MHS9yS+AvLy88I21TqeTadOmxfy8qVOn1ntTbei1dOlSIHb6zzCMelOB+3vllVe46qqrsNvtUf3jxo3jrLPOolevXlx++eW89957fPnllyxfvvxwhq71rLy88dRE+ndyMS3zaVZXnIaleD133+3nYcf3vGQzc3KaBdPkq7lyQC7pXdP4fPAV3DT5TF67YCp7vBp///w+7jrzTjyawcN7F3Fz+iAevO8l9no0Nt44kyX5F7OzqpYks8IjPwfYWrKOvql2/vreKsZmJZLstHHHjBU80ddFQmYCF89azZxLejLt8wJ8NRWcfMswNn65mEBtNSdM+gNFD35H/n/GoqZlUTZmBlmP3IjucOJ56j7UYRPx3nM7ABVdh6IH3sGkqGw256KYrZgUlSVFtVgSnXy7rRK3L4AjLZt5m0qp9mskZuXxxfo9JLk6opqtfLluD0nZHVFtDr5cs5vk3K58vbYYn0/DmduBnzaVEPDrpOa0YdPWctJcqZgtKnt3VZGenYTZqlK6201mbjKqWWHHhhI69GjDptW7MXSNLvkZ7Fy/C0PTaH9yW35dup6OWR2xmhVWVuyhc5vjsJkVvnWX0rlNEnPdwXh0h4wEfNUVwXZmAv7qCtpnJKCYTAQ8bnKcdlRT8OnQriQbimIKR6E1Xy0AaQ4LAZ8n2LZb0AI+0h0WFBNo/mA8WjGZ0P0+nHYzemQ8WtfCUWi97qnSoZhz6OnQwcizghIRfw5FpfdvR34FiEhSRz9VOqId6ldNEdHlqCdMx346dHSEmvB++/pix6pjRaH3jxo3FF2Oeqp0A5Hoho5R71OnD6F9OGJFoY92JDqyLZHo1uFIRaW3b99OSkpKuL++VZfx48c3mOzp2LEjK1euZPfu3Qe8t2fPHrKzsxs8r2+//ZZ169bx9ttvN7ht3759sVgsbNiwgb59+za4fUirmbwIIYQQzYmhN/GG3brqvCkpKVGTl/pkZmaSmZnZ4HaDBw+moqKCH3/8kQEDBgDwww8/UFFRwZAhQxrc/+WXX6Zfv3706dOnwW3XrFmD3+8nJyenwW0jyWUjIYQQQoT17NmTESNGMG7cOBYvXszixYsZN24co0aNikoa9ejRgw8//DBq38rKSt59912uu+66A467ceNG7r33XpYuXcqWLVuYPXs2l1xyCSeddBKnnHLKYZ2jTF6EEEKIeGhSgTodfsMHM86YMYPevXszfPhwhg8fzgknnMAbb7wRtc26deuoqKiI6ps5cyaGYXDFFVcccEyr1cpXX33FOeecQ/fu3bn55psZPnw4X375JaqqHtb5yWUjIYQQIg50zUBvwsMV9SY81LEh6enpvPnmmwfdJtaDIa+//nquv/76mNvn5eWxYMGCI3J+svIihBBCiBZFVl6EEEKIODA0I+bqxSHv/xuuvDR3MnkRQggh4kA3mnjZqAn7tnStZvKS+c9xbNju5u83D+L9LqdSVBtgygeT+Pfoh5m69AWMjPaMzz2bx6rXUOKFp9KPJ+8vD7P6/hNxqCZetgwiUVXItav88ZPtjMxwcNFLS6mp9DKtVxZ/e24xHreXDy/qzrmvfE+g1s1dtw1j8kfzeOO+32PNSOfXx79iwL//gurMoOiGT8ifeSd7L30RQ9dI/fP9uGf8EwDfsKn477qR0l7nUePXMSkz+cXWmRqvhtmexDfFBrbkdBSzldkbSklsk4ditvL+miKSc7ugmq2899MunG3z+fCnXbhr/TjbH8esgl3U1AZIa9+dr1YWkt6+C2aLyvKfi8ns0A6zRWHLplLa5KWxa0s5ekCnTTsne3ZUogV02nXLYNsve+h6gitYo2XxZvqf2gWbWWHrqs0MPLkdVrPCuoWr6HlmV9YsWI6ua/TM6c33ZUUYukaPnCHMrthDt+wkrGYFb1Up3VxJqCYTvqpSOmYE67kYuk5bpwN/TbByZE6ynUBtNVmJVpS62i5ZiTZUEwR8HjISrKiKiYDXQ2aCBa2uXktmgiVcuyXdEWyn2S0A6IFgbRfFZKqr52IO11dJtKrhOi92s4Kha9jMpnBtF7uqhGu+WNV9dVdsEQVWYtV8MSsmFIL7WZRgUahQf4glom2uO55ZjXx/35/r/eu/hPuVA9uKaV8dlMg6MJElRdQGaq1EHre+2i2x6rjUV88lUqx6LU2p4RKrXkt97SMtVr2W+tpCiMPXaiYvQgghRHOiGQZaE1ZPmrJvSyeTFyGEECIONCP4asr+rZWkjYQQQgjRosjKixBCCBEHctmo8WTyIoQQQsSBXDZqPJm8CCGEEHGgN3HlRaLSrcCbn28kSVUZ+NZHrH1+KImqwq01QzjJYeHChQmUle3gn53TOGXat9S4fbw5qhu/nzqX2df0xpGVxoD/fMDq+87DkZXGXa+8x8uvjeeGBz9E9/s4beZDrB8zIxgFnvM0u0fcB0DaG89QNfhv6Fc8Ralfx/fArWzrdRGegI5Jmc33pi6YHUmoZisfbDdwpLlQzBZeKygkpV0+L/y4A3dtgLSOvXjq+824a/1kdj+ZpxZsJCP/ZMxWC698s4ms7iehmBVmLdqGq/txqGYT3y3fSW6PziwtKEQL6OR2zebXtXvQAzptu6azY0MJHXq0wWZV+Xnpdk4c1AGbWWHhVz9z+jm9mPfpcgxdY+iQIXy0dA2GrnHyiHzWLFjKyZ2Ow2pWWPTJAk7udDKqYmJOyU5O6jAMq6rwbsUeerdz8mbFHgxdp4crGV9VGYau0SUzEX9NJZ0zErEoJvw1lbR3OlBMJvy11eQ5HfhrqzE0jbYpNgJeDwA5ScF2TrINxRSMRGfXxaZ1v4/spLp2wEebRCt6IBiPdtos4chzsk1FD/hItO6LOSdags/TMHQNR10kGsBu3hdzDsWfI+PRNrMpvJ9d3de2qkpUPDokFH+27hel3vf+vj+rkbHpUPzZEiP6fOC2HLS9fww6HLFuIP4c+X59kef62g1Fng8lMXw4kecjHX8+nMizxJ+FOHpazeRFCCGEaE40mnjZ6IidScsjkxchhBAiDjTDQENu2G0MiUoLIYQQokWRlRchhBAiDjSjaZd+JG0khBBCiKNKJi+NJ5eNhBBCCNGiyMqLEEIIEQdyw27jtZrJy91PX0FGu7Zk3vgwZXP/jZrWhoSxT1Gz/C3Gj34KgDOWfc6qYXcA0OmbWewcOp6Uef8PT0Cn8ty/s/uq/1DlDaC9cD/zu/4BRfkv5kQn02s6k5CRi2K28tBqP872PTFbHUz8v3W06TGIiZ/8QlWtn5yTzmL8eyvx+TTaDzibO99fSfuTh2G2qPxv1s90GnQqqqrw6qe/0OXkfrzz+QY0TafrgOOZt2AzmqbTrW9HVi3dSfe+7XBYVZZ/t4HBp3fHalaY9+lyRvz+ZKxmhY/e/pZLrzyNt9+ch65rXHjmSJ5/7v8wdI1rLhzNo3O/4y+XnRCs1/LB55x17QAsisLnb37MsB5n8PErWwAY0jmDGXu2A9C/QxrPluyiX14qqmLCU7abXq4UVBN43WUcn5WMYgJvVRk9MhPxVVdi6BrdMhLwVVcA0CUtAb/HTZe0BFQF/B43HVMdAGheD7kpNrS62i6uJBt6wIeha7RJtKAHfGQkWFAI1nNJtZsxmUAP+Eix7avXkmTZV2slyaqEa74k1PUnWBQUQrVdTJhMpgPqvES16/YL1XYBwrVdIFivJVQTpb46LqG2RTGFa5uY66nXElnzJdSOrNFirqfmS0Pt+t6PrMsSqz7ModRoqa/d2BotsfY7XI2t0RJrPyF+C3oTLxvprXfuIpeNhBBCCNGytJqVFyGEEKI5kctGjSeTFyGEECIOJG3UeDJ5EUIIIeIgOHlpysrLETyZFkbueRFCCCFEiyIrL0IIIUQcyGWjxms1k5db1RH4ix1kHZfLuT+5CPg1Og45j9PeqaDbsItQzAqnPF7A8edegmpWGPbv+fS9+ErO+ffXaJrOyZdexh8eCLYHX34xf3v0W3535WisZoWpTy1g+JXn4bCaeeal+Vx01dlYVYX3Z37DFVefzluvf4UW8PGXG0aF48qTJl7Mf//7DlMmX46qmJh6z3QeuPdPKCYT/5jyIo8+eD233v4cAHdd8zduuPVJAP7z11v443uzeHj8baiKibmvvc0f7xiOYjLxwXMzuKLfRSgmmP7IekafcDkv7tqIoWuc2zOLR4q2ADC8WxvuL9nFGZ0zURXwlO1maId0TCaordjLwLapeKtKAeiXmxJu93El4auu4LisRBRMBDxuemQmABDwuOmcZgdA83lo77Sh+TwYukbb5GAbIDvJgubzkJ0Y/KOnB3xkOPa10+3mcLQ5za6G26l2FUPXcNrUcMzZaQsuHBq6RrI1IiptVaOi0iGJdbnjRIsSjvMmROSSHRFRaEeMWHRkPNpmVmK2G4pKR/ZZ6mnHilBHxaMbiDYH26YD2rH69m83FFc+3PaRjCsfbluI5k5u2G08uWwkhBBCiBal1ay8CCGEEM2JAehN3L+1ksmLEEIIEQdy2ajx5LKREEIIIVoUWXkRQggh4kDSRo0nkxchhBAiDuSyUeO1msnLR0+/jEm1UrnwaVKG3AgQblcufBogZju07YqI9upHgu21j9dt+/QLTH/2D8H2f5/iifPHAPDC/Y/xwPBreWrqowD88/TxPHTnWgAmDGrHvwo38rf+uQD8fc92/tQnG4CbSnZx5fFtuKGsCIDRPTL4Y8UeAM7rmoa3qpSRXVIB8FdXMKxDSrh9arskAAK1bgbmJhKodQPQNzshHFfu3caO5vNwfKYNCEaU89Os4XaXVEs4otzZaQnHjjskB9sdki1AMJbcLskcbucm7mvnJJrD+2UnqOH/DlmOYDvTsa8vw67EbKfZ9rVT6yLPqRHR55SIdrLFFLOdaD6wHdmXUE87MhYdMyodccG1vnbEaYTbsfr2b5tjtGP1HaytRPxCDLVj9R1Ku7H7AZjqfrmajAP7DqXd2P3ks+Wzm7KfaP5azeRFCCGEaE7kslHjyeRFCCGEiAO5bNR4MnkRQggh4kBv4sqL3nrnLi0jKv3MM8/QqVMn7HY7/fr149tvv433KQkhhBAiTpr95OXtt99mwoQJTJkyhRUrVvC73/2OkSNHsm3btnifmhBCCNFommE0+dVaNfvJy6OPPsq1117LddddR8+ePXnsscfIy8vj2WefjfepCSGEEI2mUXfTbmNf8f4B4qhZ3/Pi8/lYtmwZd9xxR1T/8OHDWbhwYcx9vF4vXq83/H1FRQUAhuYHoLKyEkPzRbUrKyvrtjmwvf+2h7rfkTiGfLZ8tny2fLZ89tH+7OD/K4yjsKrha9KTjZq+f4tmNGM7d+40AOP777+P6v/3v/9t5Ofnx9zn7rvvNgg+r0pe8pKXvOQlr0a9tm/f/pv9v83j8Rgul+uInKfL5TI8Hs9vdq7NVbNeeQkxmUxR3xuGcUBfyOTJk5k4cWL4+/Lycjp06MC2bdtwOp2/6XkeSyorK8nLy2P79u2kpKTE+3RaBBmzxpFxO3wyZo1zKONmGAZVVVXk5ub+Zudht9vZvHkzPp+vyceyWq3Y7fYjcFYtS7OevGRmZqKqKkVFRVH9xcXFZGdnx9zHZrNhs9kO6Hc6nfKXvBFSUlJk3A6TjFnjyLgdPhmzxmlo3I7GP3TtdnurnHQcKc36hl2r1Uq/fv2YO3duVP/cuXMZMmRInM5KCCGEEPHUrFdeACZOnMiYMWPo378/gwcP5oUXXmDbtm3ccMMN8T41IYQQQsRBs5+8XHbZZZSUlHDvvfdSWFhIr169mD17Nh06dDik/W02G3fffXfMS0mifjJuh0/GrHFk3A6fjFnjyLgdO0yG0Yqr3AghhBCixWnW97wIIYQQQuxPJi9CCCGEaFFk8iKEEEKIFkUmL0IIIYRoUY7pycszzzxDp06dsNvt9OvXj2+//TbepxRX33zzDeeffz65ubmYTCY++uijqPcNw2Dq1Knk5ubicDg4/fTTWbNmTdQ2Xq+Xm266iczMTBITE7ngggvYsWPHUfwpjq5p06Zx8sknk5ycTFZWFhdeeCHr1q2L2kbGLdqzzz7LCSecEC4ENnjwYD777LPw+zJeDZs2bRomk4kJEyaE+2TcDjR16lRMJlPUy+Vyhd+XMTuGxe3BBL+xmTNnGhaLxXjxxReNn3/+2bjllluMxMREY+vWrfE+tbiZPXu2MWXKFOP99983AOPDDz+Mev/BBx80kpOTjffff99YtWqVcdlllxk5OTlGZWVleJsbbrjBaNu2rTF37lxj+fLlxrBhw4w+ffoYgUDgKP80R8c555xjvPrqq8bq1auNgoIC47zzzjPat29vuN3u8DYybtE+/vhj49NPPzXWrVtnrFu3zrjzzjsNi8VirF692jAMGa+G/Pjjj0bHjh2NE044wbjlllvC/TJuB7r77ruN448/3igsLAy/iouLw+/LmB27jtnJy4ABA4wbbrghqq9Hjx7GHXfcEaczal72n7zoum64XC7jwQcfDPfV1tYaTqfTeO655wzDMIzy8nLDYrEYM2fODG+zc+dOQ1EUY86cOUft3OOpuLjYAIwFCxYYhiHjdqjS0tKMl156ScarAVVVVUa3bt2MuXPnGqeddlp48iLjFtvdd99t9OnTJ+Z7MmbHtmPyspHP52PZsmUMHz48qn/48OEsXLgwTmfVvG3evJmioqKoMbPZbJx22mnhMVu2bBl+vz9qm9zcXHr16tVqxrWiogKA9PR0QMatIZqmMXPmTKqrqxk8eLCMVwNuvPFGzjvvPM4666yofhm3+m3YsIHc3Fw6derE5ZdfzqZNmwAZs2Nds6+w2xh79+5F07QDHt6YnZ19wEMeRVBoXGKN2datW8PbWK1W0tLSDtimNYyrYRhMnDiRU089lV69egEybvVZtWoVgwcPpra2lqSkJD788EOOO+648P8QZLwONHPmTJYvX86SJUsOeE/+nMU2cOBAXn/9dfLz89m9ezf3338/Q4YMYc2aNTJmx7hjcvISYjKZor43DOOAPhGtMWPWWsZ1/PjxrFy5ku++++6A92TconXv3p2CggLKy8t5//33GTt2LAsWLAi/L+MVbfv27dxyyy188cUXB33SsIxbtJEjR4bbvXv3ZvDgwXTp0oXp06czaNAgQMbsWHVMXjbKzMxEVdUDZs7FxcUHzMJFUOgO/YONmcvlwufzUVZWVu82x6qbbrqJjz/+mK+//pp27dqF+2XcYrNarXTt2pX+/fszbdo0+vTpw+OPPy7jVY9ly5ZRXFxMv379MJvNmM1mFixYwBNPPIHZbA7/3DJuB5eYmEjv3r3ZsGGD/Fk7xh2Tkxer1Uq/fv2YO3duVP/cuXMZMmRInM6qeevUqRMulytqzHw+HwsWLAiPWb9+/bBYLFHbFBYWsnr16mN2XA3DYPz48XzwwQfMmzePTp06Rb0v43ZoDMPA6/XKeNXjzDPPZNWqVRQUFIRf/fv356qrrqKgoIDOnTvLuB0Cr9fL2rVrycnJkT9rx7p43CV8NISi0i+//LLx888/GxMmTDASExONLVu2xPvU4qaqqspYsWKFsWLFCgMwHn30UWPFihXh+PiDDz5oOJ1O44MPPjBWrVplXHHFFTFjhe3atTO+/PJLY/ny5cYZZ5xxTMcK//rXvxpOp9OYP39+VByzpqYmvI2MW7TJkycb33zzjbF582Zj5cqVxp133mkoimJ88cUXhmHIeB2qyLSRYci4xXLbbbcZ8+fPNzZt2mQsXrzYGDVqlJGcnBz+PS9jduw6ZicvhmEYTz/9tNGhQwfDarUaffv2DcdbW6uvv/7aAA54jR071jCMYLTw7rvvNlwul2Gz2YyhQ4caq1atijqGx+Mxxo8fb6SnpxsOh8MYNWqUsW3btjj8NEdHrPECjFdffTW8jYxbtD//+c/hv3dt2rQxzjzzzPDExTBkvA7V/pMXGbcDheq2WCwWIzc31xg9erSxZs2a8PsyZscuk2EYRnzWfIQQQgghDt8xec+LEEIIIY5dMnkRQgghRIsikxchhBBCtCgyeRFCCCFEiyKTFyGEEEK0KDJ5EUIIIUSLIpMXIYQQQrQoMnkRQhyyLVu2YDKZKCgoiPepCCFaMZm8CNGC/PGPf8RkMmEymbBYLGRnZ3P22WfzyiuvoOv6Ef+sCy+88IgeUwghjgSZvAjRwowYMYLCwkK2bNnCZ599xrBhw7jlllsYNWoUgUAg3qcnhBC/OZm8CNHC2Gw2XC4Xbdu2pW/fvtx5553MmjWLzz77jNdeew2AiooKrr/+erKyskhJSeGMM87gp59+Ch9j6tSpnHjiiTz//PPk5eWRkJDAJZdcQnl5efj96dOnM2vWrPBKz/z588P7b9q0iWHDhpGQkECfPn1YtGjRURwBIURrJ5MXIY4BZ5xxBn369OGDDz7AMAzOO+88ioqKmD17NsuWLaNv376ceeaZlJaWhvf59ddfeeedd/jkk0+YM2cOBQUF3HjjjQBMmjSJSy+9NLzKU1hYyJAhQ8L7TpkyhUmTJlFQUEB+fj5XXHGFrPoIIY4ambwIcYzo0aMHW7Zs4euvv2bVqlW8++679O/fn27duvHwww+TmprKe++9F96+traW6dOnc+KJJzJ06FCefPJJZs6cSVFREUlJSTgcjvAqj8vlwmq1hvedNGkS5513Hvn5+dxzzz1s3bqVX3/9NR4/thCiFZLJixDHCMMwMJlMLFu2DLfbTUZGBklJSeHX5s2b2bhxY3j79u3b065du/D3gwcPRtd11q1b1+BnnXDCCeF2Tk4OAMXFxUfwpxFCiPqZ430CQogjY+3atXTq1Ald18nJyYm6RyUkNTW13v1NJlPU14OxWCwH7Hek005CCFEfmbwIcQyYN28eq1at4tZbb6Vdu3YUFRVhNpvp2LFjvfts27aNXbt2kZubC8CiRYtQFIX8/HwArFYrmqYdjdMXQojDIpMXIVoYr9dLUVERmqaxe/du5syZw7Rp0xg1ahTXXHMNiqIwePBgLrzwQv7zn//QvXt3du3axezZs7nwwgvp378/AHa7nbFjx/Lwww9TWVnJzTffzKWXXorL5QKgY8eOfP7556xbt46MjAycTmc8f2whhAiTyYsQLcycOXPIycnBbDaTlpZGnz59eOKJJxg7diyKEryNbfbs2UyZMoU///nP7NmzB5fLxdChQ8nOzg4fp2vXrowePZpzzz2X0tJSzj33XJ555pnw++PGjWP+/Pn0798ft9vN119/fdCVHCGEOFpMhmEY8T4JIcTRNXXqVD766CMp8y+EaJEkbSSEEEKIFkUmL0IIIYRoUeSykRBCCCFaFFl5EUIIIUSLIpMXIYQQQrQoMnkRQgghRIsikxchhBBCtCgyeRFCCCFEiyKTFyGEEEK0KDJ5EUIIIUSLIpMXIYQQQrQoMnkRQgghRIvy/wFaui5eHR6YagAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_get_angles()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### PHOC API兼容测试\n",
    "注意,原本的Data,即Words List经过编码后返回一个(batch,encode)维度的张量\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The content of Encoded word: tensor([[ 0.0000e+00,  1.0000e+00,  0.0000e+00,  ...,  1.0000e+00,\n",
      "          0.0000e+00,  1.0000e+00],\n",
      "        [ 8.4147e-01,  5.4030e-01,  8.2288e-01,  ...,  1.0000e+00,\n",
      "          1.0347e-04,  1.0000e+00],\n",
      "        [ 9.0930e-01, -4.1615e-01,  9.3514e-01,  ...,  1.0000e+00,\n",
      "          2.0694e-04,  1.0000e+00],\n",
      "        ...,\n",
      "        [-7.5680e-01, -6.5364e-01, -6.6258e-01,  ...,  1.0000e+00,\n",
      "          4.1388e-04,  1.0000e+00],\n",
      "        [-9.5892e-01,  2.8366e-01, -9.9282e-01,  ...,  1.0000e+00,\n",
      "          5.1735e-04,  1.0000e+00],\n",
      "        [-2.7942e-01,  9.6017e-01, -4.6568e-01,  ...,  1.0000e+00,\n",
      "          6.2082e-04,  1.0000e+00]])\n",
      "Encoded word shape: torch.Size([7, 540])\n"
     ]
    }
   ],
   "source": [
    "# 添加具体Data的编码结果\n",
    "# Example usage:\n",
    "words = ['p', '309', 'letters', 'orders', 'and', 'instructions', 'december']\n",
    "encoder = PositionalEncoder()\n",
    "encoder.init_pos_encoding(position_model=50, d_model=540)\n",
    "encoded_words = encoder.encode(words)\n",
    "\n",
    "print(\"The content of Encoded word:\", encoded_words)\n",
    "print(\"Encoded word shape:\", encoded_words.shape)   # Output should be [7, 540]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Positional Encoding Shape: torch.Size([1, 4, 8])\n",
      "Positional Encoding Tensor:\n",
      " tensor([[[ 0.0000e+00,  1.0000e+00,  0.0000e+00,  1.0000e+00,  0.0000e+00,\n",
      "           1.0000e+00,  0.0000e+00,  1.0000e+00],\n",
      "         [ 8.4147e-01,  5.4030e-01,  9.9833e-02,  9.9500e-01,  9.9998e-03,\n",
      "           9.9995e-01,  1.0000e-03,  1.0000e+00],\n",
      "         [ 9.0930e-01, -4.1615e-01,  1.9867e-01,  9.8007e-01,  1.9999e-02,\n",
      "           9.9980e-01,  2.0000e-03,  1.0000e+00],\n",
      "         [ 1.4112e-01, -9.8999e-01,  2.9552e-01,  9.5534e-01,  2.9996e-02,\n",
      "           9.9955e-01,  3.0000e-03,  1.0000e+00]]])\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 实际测试\n",
    "def test_positional_encoding():\n",
    "    position_encoder = PositionalEncoder()\n",
    "    \n",
    "    # 设定句子长度和维度\n",
    "    sentence_length = 4     # 例如 \"I love NLP\" 中有 4 个词\n",
    "    d_model = 8             # 设置位置编码的维度为 8\n",
    "\n",
    "    # 生成位置编码\n",
    "    pos_encoding = position_encoder.positional_encoding(position_model=sentence_length, d_model=d_model)\n",
    "    print(\"Positional Encoding Shape:\", pos_encoding.shape)\n",
    "    print(\"Positional Encoding Tensor:\\n\", pos_encoding)\n",
    "\n",
    "    # 绘制位置编码\n",
    "    position_encoder.draw_pos_encoding()\n",
    "\n",
    "test_positional_encoding()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "positional_encoding 方法:\n",
    "\n",
    "    angle_rads 计算每个位置和维度的角度值，结果是形状为 [4, 8] 的数组（即 [sentence_length, d_model]）。\n",
    "    self.pos_encoding 通过在前面添加一个批次维度，变成了形状为 [1, 4, 8] 的张量。\n",
    "positional_encoding 方法:\n",
    "\n",
    "    angle_rads 计算每个位置和维度的角度值，结果是形状为 [4, 8] 的数组（即 [sentence_length, d_model]）。\n",
    "    self.pos_encoding 通过在前面添加一个批次维度，变成了形状为 [1, 4, 8] 的张量。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 具体数据测试\n",
    "关于具体数据\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transformer实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EncoderLayer 类定义\n",
    "class EncoderLayer(nn.Module):\n",
    "    \"\"\"实现了 Transformer 编码器的基本层，包括自注意力机制和前馈网络。\n",
    "\n",
    "    Args:\n",
    "        nn (_type_): _description_\n",
    "    \"\"\"    \n",
    "    def __init__(self, d_model, num_heads, dff, rate=0.1):\n",
    "        super(EncoderLayer, self).__init__()\n",
    "        self.attention = nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads)\n",
    "        self.ffn = nn.Sequential(\n",
    "            nn.Linear(d_model, dff),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(dff, d_model)\n",
    "        )\n",
    "        self.layernorm1 = nn.LayerNorm(d_model)\n",
    "        self.layernorm2 = nn.LayerNorm(d_model)\n",
    "        self.dropout = nn.Dropout(rate)\n",
    "\n",
    "    def forward(self, x, mask):\n",
    "        attn_output, _ = self.attention(x, x, x, attn_mask=mask)\n",
    "        x = self.layernorm1(x + self.dropout(attn_output))\n",
    "        ffn_output = self.ffn(x)\n",
    "        x = self.layernorm2(x + self.dropout(ffn_output))\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Encoder 类定义\n",
    "class Encoder(nn.Module):\n",
    "    \"\"\"词嵌入层、位置编码层和多个编码器层。\n",
    "\n",
    "    Args:\n",
    "        nn (_type_): _description_\n",
    "    \"\"\"    \n",
    "    def __init__(\n",
    "        self,\n",
    "        num_layers,\n",
    "        d_model,\n",
    "        num_heads,\n",
    "        dff,\n",
    "        input_vocab_size,\n",
    "        maximum_position_encoding,\n",
    "        rate=0.1\n",
    "    ):\n",
    "        super(Encoder, self).__init__()\n",
    "\n",
    "        self.positional_encoder = PositionalEncoder()\n",
    "        self.num_layers = num_layers\n",
    "        self.d_model = d_model\n",
    "\n",
    "        self.embedding = nn.Embedding(\n",
    "            num_embeddings=input_vocab_size, embedding_dim=d_model\n",
    "        )\n",
    "        self.pos_encoding = self.positional_encoder.positional_encoding(\n",
    "            maximum_position_encoding, d_model\n",
    "        )\n",
    "\n",
    "        self.enc_layers = nn.ModuleList(\n",
    "            [EncoderLayer(d_model, num_heads, dff, rate) for _ in range(num_layers)]\n",
    "        )\n",
    "        self.dropout = nn.Dropout(rate)\n",
    "\n",
    "    def forward(self, x, mask):\n",
    "        inp_seq_len = x.shape[-1]\n",
    "\n",
    "        # adding embedding and position encoding 先进行词嵌入并缩放。\n",
    "        x = self.embedding(x)  # [b, inp_seq_len] => [b, inp_seq_len, d_model]\n",
    "        x *= torch.sqrt(torch.tensor(self.d_model, dtype=torch.float32))\n",
    "        pos_encoding = self.pos_encoding[:, :inp_seq_len, :]\n",
    "        # 添加位置编码。\n",
    "        x += pos_encoding  # [b, inp_seq_len, d_model]\n",
    "\n",
    "        x = self.dropout(x)\n",
    "        \n",
    "        # 通过每个编码器层处理数据。\n",
    "        for i in range(self.num_layers):\n",
    "            x = self.enc_layers[i](x, mask)  # [b, inp_seq_len, d_model] => [b, inp_seq_len, d_model]\n",
    "        return x  # [b, inp_seq_len, d_model]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 示例使用\n",
    "def transformer_test():\n",
    "    input_vocab_size = 10000\n",
    "    maximum_position_encoding = 50\n",
    "    d_model = 512\n",
    "    num_heads = 8\n",
    "    dff = 2048\n",
    "    num_layers = 6\n",
    "    rate = 0.1\n",
    "\n",
    "    encoder = Encoder(\n",
    "        num_layers=num_layers,\n",
    "        d_model=d_model,\n",
    "        num_heads=num_heads,\n",
    "        dff=dff,\n",
    "        input_vocab_size=input_vocab_size,\n",
    "        maximum_position_encoding=maximum_position_encoding,\n",
    "        rate=rate\n",
    "    )\n",
    "\n",
    "    x = torch.randint(0, input_vocab_size, (2, maximum_position_encoding))  # Batch of 2, sequence length 50\n",
    "    mask = None  # Assuming no mask for simplicity\n",
    "\n",
    "    output = encoder(x, mask)\n",
    "    print(\"Output shape:\", output.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Output shape: torch.Size([2, 50, 512])\n"
     ]
    }
   ],
   "source": [
    "transformer_test()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "science39",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
